mirror of
https://gitee.com/BDWare/cp.git
synced 2026-01-29 01:29:27 +00:00
initial commit
This commit is contained in:
337
src/main/data-mask/maskingJobs/MaskingJob.java
Normal file
337
src/main/data-mask/maskingJobs/MaskingJob.java
Normal file
@@ -0,0 +1,337 @@
|
||||
package maskingJobs;
|
||||
|
||||
import com.alibaba.datax.common.element.*;
|
||||
import com.alibaba.datax.common.exception.DataXException;
|
||||
import com.alibaba.datax.common.util.Configuration;
|
||||
import com.alibaba.datax.core.transport.record.DefaultRecord;
|
||||
import com.alibaba.datax.core.transport.transformer.TransformerErrorCode;
|
||||
import com.alibaba.datax.core.transport.transformer.TransformerExecution;
|
||||
|
||||
import com.alibaba.datax.core.util.TransformerUtil;
|
||||
import com.alibaba.datax.core.util.container.ClassLoaderSwapper;
|
||||
import com.alibaba.datax.core.util.container.CoreConstant;
|
||||
import com.alibaba.datax.plugin.rdbms.reader.Key;
|
||||
import com.alibaba.datax.plugin.rdbms.reader.util.SingleTableSplitUtil;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DBUtil;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DBUtilErrorCode;
|
||||
import com.alibaba.datax.plugin.rdbms.util.DataBaseType;
|
||||
import com.alibaba.datax.plugin.rdbms.util.RdbmsException;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.apache.commons.lang3.Validate;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.ResultSetMetaData;
|
||||
import java.sql.Types;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public class MaskingJob {
|
||||
|
||||
DataBaseType dataBaseType = DataBaseType.MySql;
|
||||
private String username;
|
||||
private String password;
|
||||
private String jdbcUrl;
|
||||
private String table;
|
||||
private Configuration maskConf;
|
||||
private Configuration readerPara;
|
||||
private List<Record> buffer;
|
||||
private List<TransformerExecution> transformerExecs;
|
||||
|
||||
|
||||
public void init(String confContent) {
|
||||
maskConf = Configuration.from(confContent);
|
||||
System.out.println("maskConf"+maskConf.toString());
|
||||
System.out.println(("maskCOnfjob"+maskConf.get("job").toString()));
|
||||
readerPara = maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT_READER_PARAMETER);
|
||||
System.out.println(readerPara);
|
||||
username = readerPara.getString(Key.USERNAME);
|
||||
password = readerPara.getString(Key.PASSWORD);
|
||||
jdbcUrl = readerPara.getString(Key.JDBC_URL);
|
||||
table = readerPara.getString(Key.TABLE);
|
||||
buffer = new ArrayList<>();
|
||||
System.out.println("maskConf11"+maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT + "[0]"));
|
||||
transformerExecs = TransformerUtil.buildTransformerInfo(maskConf.getConfiguration(CoreConstant.DATAX_JOB_CONTENT + "[0]"));
|
||||
}
|
||||
|
||||
public String buildQuerySql() {
|
||||
String column = "*";
|
||||
//String column = readerPara.getString(Key.COLUMN);
|
||||
String table = readerPara.getString(Key.TABLE);
|
||||
String where = readerPara.getString(Key.WHERE, null);
|
||||
//String querySql = SingleTableSplitUtil.buildQuerySql(column, table, where) + " limit 100";
|
||||
String querySql = SingleTableSplitUtil.buildQuerySql(column, table, where) + " limit 100";
|
||||
|
||||
return querySql;
|
||||
}
|
||||
|
||||
public JsonPrimitive getMaskedData(String confContent) {
|
||||
init(confContent);
|
||||
return startRead();
|
||||
//return new JsonPrimitive(getResult());
|
||||
}
|
||||
|
||||
public JsonPrimitive startRead() {
|
||||
String querySql = buildQuerySql();
|
||||
System.out.println("startRead"+dataBaseType+jdbcUrl+username+password);
|
||||
Connection conn = DBUtil.getConnection(dataBaseType, jdbcUrl, username, password);
|
||||
System.out.println(dataBaseType+jdbcUrl+username+password);
|
||||
int columnNumber = 0;
|
||||
String res="";
|
||||
ArrayList<String>columnName=new ArrayList<>();
|
||||
try {
|
||||
ResultSet rs = DBUtil.query(conn, querySql);
|
||||
ResultSetMetaData metaData = rs.getMetaData();
|
||||
columnNumber = metaData.getColumnCount();
|
||||
for(int i=1;i<=metaData.getColumnCount();i++){
|
||||
//获取列表 index 从1开始、列名、列类型、列的数据长度
|
||||
//System.out.println("aaa"+metaData.getColumnName(i)+"\t"+metaData.getColumnTypeName(i)+"\t"+metaData.getColumnDisplaySize(i));
|
||||
columnName.add(metaData.getColumnName(i));
|
||||
|
||||
}
|
||||
|
||||
while (rs.next()) {
|
||||
transportOneRecord(rs, metaData, columnNumber);
|
||||
}
|
||||
|
||||
|
||||
} catch (Exception e) {
|
||||
throw RdbmsException.asQueryException(dataBaseType, e, querySql, table, username);
|
||||
} finally {
|
||||
DBUtil.closeDBResources(null, conn);
|
||||
}
|
||||
////for(int i=0;i<columnNumber;i++){
|
||||
//columnName.add(metaData.getColumnName(i));
|
||||
//}//
|
||||
res=getResult(columnName);
|
||||
return new JsonPrimitive(res);
|
||||
}
|
||||
|
||||
private Record transportOneRecord(ResultSet rs, ResultSetMetaData metaData,
|
||||
int columnNumber) {
|
||||
Record record = buildRecord(rs, metaData, columnNumber);
|
||||
sendToWriter(record);
|
||||
return record;
|
||||
}
|
||||
|
||||
private void sendToWriter(Record record) {
|
||||
Validate.notNull(record, "record不能为空.");
|
||||
|
||||
record = doTransformer(record);
|
||||
|
||||
if (record == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.buffer.add(record);
|
||||
}
|
||||
|
||||
private Record doTransformer(Record record) {
|
||||
System.out.println("Record"+record);
|
||||
if (transformerExecs == null || transformerExecs.size() == 0) {
|
||||
return record;
|
||||
}
|
||||
|
||||
ClassLoaderSwapper classLoaderSwapper = ClassLoaderSwapper
|
||||
.newCurrentThreadClassLoaderSwapper();
|
||||
|
||||
Record result = record;
|
||||
|
||||
String errorMsg = null;
|
||||
boolean failed = false;
|
||||
for (TransformerExecution transformerInfoExec : transformerExecs) {
|
||||
System.out.println("transformerExecs"+transformerInfoExec.getTransformerName());
|
||||
if (transformerInfoExec.getClassLoader() != null) {
|
||||
classLoaderSwapper.setCurrentThreadClassLoader(transformerInfoExec.getClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* 延迟检查transformer参数的有效性,直接抛出异常,不作为脏数据
|
||||
* 不需要在插件中检查参数的有效性。但参数的个数等和插件相关的参数,在插件内部检查
|
||||
*/
|
||||
if (!transformerInfoExec.isChecked()) {
|
||||
|
||||
if (transformerInfoExec.getColumnIndex() != null && transformerInfoExec.getColumnIndex() >= record.getColumnNumber()) {
|
||||
throw DataXException.asDataXException(TransformerErrorCode.TRANSFORMER_ILLEGAL_PARAMETER,
|
||||
String.format("columnIndex[%s] out of bound[%s]. name=%s",
|
||||
transformerInfoExec.getColumnIndex(), record.getColumnNumber(),
|
||||
transformerInfoExec.getTransformerName()));
|
||||
}
|
||||
transformerInfoExec.setIsChecked(true);
|
||||
}
|
||||
|
||||
try {
|
||||
result = transformerInfoExec.getTransformer().evaluate(result, transformerInfoExec.gettContext(), transformerInfoExec.getFinalParas());
|
||||
} catch (Exception e) {
|
||||
errorMsg = String.format("transformer(%s) has Exception(%s)", transformerInfoExec.getTransformerName(),
|
||||
e.getMessage());
|
||||
failed = true;
|
||||
//LOG.error(errorMsg, e);
|
||||
// transformerInfoExec.addFailedRecords(1);
|
||||
//脏数据不再进行后续transformer处理,按脏数据处理,并过滤该record。
|
||||
break;
|
||||
|
||||
} finally {
|
||||
if (transformerInfoExec.getClassLoader() != null) {
|
||||
classLoaderSwapper.restoreCurrentThreadClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
if (result == null) {
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (failed) {
|
||||
return null;
|
||||
} else {
|
||||
System.out.println("result"+result);
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected Record buildRecord(ResultSet rs, ResultSetMetaData metaData,
|
||||
int columnNumber) {
|
||||
final byte[] EMPTY_CHAR_ARRAY = new byte[0];
|
||||
Record record = new DefaultRecord();
|
||||
try {
|
||||
for (int i = 1; i <= columnNumber; i++) {
|
||||
switch (metaData.getColumnType(i)) {
|
||||
|
||||
case Types.CHAR:
|
||||
case Types.NCHAR:
|
||||
case Types.VARCHAR:
|
||||
case Types.LONGVARCHAR:
|
||||
case Types.NVARCHAR:
|
||||
case Types.LONGNVARCHAR:
|
||||
case Types.CLOB:
|
||||
case Types.NCLOB:
|
||||
record.addColumn(new StringColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.SMALLINT:
|
||||
case Types.TINYINT:
|
||||
case Types.INTEGER:
|
||||
case Types.BIGINT:
|
||||
record.addColumn(new LongColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.NUMERIC:
|
||||
case Types.DECIMAL:
|
||||
record.addColumn(new DoubleColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.FLOAT:
|
||||
case Types.REAL:
|
||||
case Types.DOUBLE:
|
||||
record.addColumn(new DoubleColumn(rs.getString(i)));
|
||||
break;
|
||||
|
||||
case Types.TIME:
|
||||
record.addColumn(new DateColumn(rs.getTime(i)));
|
||||
break;
|
||||
|
||||
// for mysql bug, see http://bugs.mysql.com/bug.php?id=35115
|
||||
case Types.DATE:
|
||||
if (metaData.getColumnTypeName(i).equalsIgnoreCase("year")) {
|
||||
record.addColumn(new LongColumn(rs.getInt(i)));
|
||||
} else {
|
||||
record.addColumn(new DateColumn(rs.getDate(i)));
|
||||
}
|
||||
break;
|
||||
|
||||
case Types.TIMESTAMP:
|
||||
record.addColumn(new DateColumn(rs.getTimestamp(i)));
|
||||
break;
|
||||
|
||||
case Types.BINARY:
|
||||
case Types.VARBINARY:
|
||||
case Types.BLOB:
|
||||
case Types.LONGVARBINARY:
|
||||
record.addColumn(new BytesColumn(rs.getBytes(i)));
|
||||
break;
|
||||
|
||||
// warn: bit(1) -> Types.BIT 可使用BoolColumn
|
||||
// warn: bit(>1) -> Types.VARBINARY 可使用BytesColumn
|
||||
case Types.BOOLEAN:
|
||||
case Types.BIT:
|
||||
record.addColumn(new BoolColumn(rs.getBoolean(i)));
|
||||
break;
|
||||
|
||||
case Types.NULL:
|
||||
String stringData = null;
|
||||
if (rs.getObject(i) != null) {
|
||||
stringData = rs.getObject(i).toString();
|
||||
}
|
||||
record.addColumn(new StringColumn(stringData));
|
||||
break;
|
||||
|
||||
default:
|
||||
throw DataXException
|
||||
.asDataXException(
|
||||
DBUtilErrorCode.UNSUPPORTED_TYPE,
|
||||
String.format(
|
||||
"您的配置文件中的列配置信息有误. 因为DataX 不支持数据库读取这种字段类型. 字段名:[%s], 字段名称:[%s], 字段Java类型:[%s]. 请尝试使用数据库函数将其转换datax支持的类型 或者不同步该字段 .",
|
||||
metaData.getColumnName(i),
|
||||
metaData.getColumnType(i),
|
||||
metaData.getColumnClassName(i)));
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
if (e instanceof DataXException) {
|
||||
throw (DataXException) e;
|
||||
}
|
||||
}
|
||||
return record;
|
||||
}
|
||||
|
||||
// private String recordToString(Record record) {
|
||||
// final String NEWLINE_FLAG = "\n";
|
||||
// String fieldDelimiter = "\t";
|
||||
//
|
||||
// int recordLength = record.getColumnNumber();
|
||||
// if (0 == recordLength) {
|
||||
// return NEWLINE_FLAG;
|
||||
// }
|
||||
//
|
||||
// Column column;
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (int i = 0; i < recordLength; i++) {
|
||||
// column = record.getColumn(i);
|
||||
// sb.append(column.asString()).append(fieldDelimiter);
|
||||
// }
|
||||
// sb.setLength(sb.length() - 1);
|
||||
// sb.append(NEWLINE_FLAG);
|
||||
//
|
||||
// return sb.toString();
|
||||
// }
|
||||
|
||||
public String getResult(ArrayList<String> columnName) {
|
||||
List<Object> dataList = new ArrayList<>();
|
||||
int size = buffer.size();
|
||||
//System.out.println("CCULUMN"+readerPara.getString(Key.COLUMN).toString());
|
||||
//String[] colmnNames = readerPara.getString(Key.COLUMN).replace(" ", "").split(",");
|
||||
int colmnSize= columnName.size();
|
||||
for (int i = 0; i < colmnSize; ++i) {
|
||||
Map<Object, Object> rowData = new HashMap<>();
|
||||
for (int j = 0; j < size; ++j) {
|
||||
rowData.put(columnName.get(i), buffer.get(j).getColumn(i).asString());
|
||||
}
|
||||
dataList.add(rowData);
|
||||
}
|
||||
|
||||
|
||||
return JsonUtil.toJson(dataList);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1309
src/main/java/org/bdware/sc/ContractProcess.java
Normal file
1309
src/main/java/org/bdware/sc/ContractProcess.java
Normal file
File diff suppressed because it is too large
Load Diff
122
src/main/java/org/bdware/sc/analysis/dynamic/FSAnalysis.java
Normal file
122
src/main/java/org/bdware/sc/analysis/dynamic/FSAnalysis.java
Normal file
@@ -0,0 +1,122 @@
|
||||
package org.bdware.sc.analysis.dynamic;
|
||||
|
||||
import org.bdware.analysis.BasicBlock;
|
||||
import org.bdware.analysis.BreadthFirstSearch;
|
||||
import org.bdware.analysis.taint.*;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.compiler.YJSCompiler;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.ContractZipBundle;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.ClassNode;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.FileInputStream;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class FSAnalysis extends BreadthFirstSearch<TaintResult, TaintBB> {
|
||||
TaintCFG cfg;
|
||||
public static boolean isDebug = false;
|
||||
|
||||
public FSAnalysis(TaintCFG cfg) {
|
||||
this.cfg = cfg;
|
||||
List<TaintBB> toAnalysis = new ArrayList<>();
|
||||
// TODO add inputBlock!
|
||||
TaintBB b = (TaintBB) cfg.getBasicBlockAt(0);
|
||||
|
||||
b.preResult = new TaintResult();
|
||||
// local0=scriptfuncion, is not tainted;
|
||||
// local1=this, is not tainted;
|
||||
// local2=this, is not tainted;
|
||||
|
||||
b.preResult.frame.setLocal(0, HeapObject.getRootObject());
|
||||
b.preResult.frame.setLocal(1, new TaintValue(1, 0));
|
||||
b.preResult.frame.setLocal(2, new TaintValue(1, 1));
|
||||
|
||||
b.preResult.ret = new TaintValue(1);
|
||||
TaintResult.printer.setLabelOrder(cfg.getLabelOrder());
|
||||
toAnalysis.add(b);
|
||||
b.setInList(true);
|
||||
setToAnalysis(toAnalysis);
|
||||
if (isDebug) {
|
||||
System.out.println("===Method:" + cfg.getMethodNode().name + cfg.getMethodNode().desc);
|
||||
System.out.println(
|
||||
"===Local:"
|
||||
+ cfg.getMethodNode().maxLocals
|
||||
+ " "
|
||||
+ cfg.getMethodNode().maxStack);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public TaintResult execute(TaintBB t) {
|
||||
return t.forwardAnalysis();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TaintBB> getSuc(TaintBB t) {
|
||||
Set<BasicBlock> subBlock = cfg.getSucBlocks(t);
|
||||
Set<TaintBB> ret = new HashSet<>();
|
||||
for (BasicBlock bb : subBlock) {
|
||||
TaintBB ntbb = (TaintBB) bb;
|
||||
ntbb.preResult.mergeResult(t.sucResult);
|
||||
ret.add(ntbb);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String staticVerify(Contract c) {
|
||||
try {
|
||||
String script = c.getScriptStr();
|
||||
ContractNode cn = null;
|
||||
YJSCompiler compiler = new YJSCompiler();
|
||||
if (script.startsWith("/")) {
|
||||
String zipPath = script;
|
||||
ZipFile zf = new ZipFile(zipPath);
|
||||
ContractZipBundle czb = compiler.compile(zf);
|
||||
cn = czb.mergeContractNode();
|
||||
} else {
|
||||
cn =
|
||||
compiler.compile(
|
||||
new ByteArrayInputStream(script.getBytes()), "contract_main.yjs");
|
||||
}
|
||||
DesktopEngine engine = new DesktopEngine(); // engine.loadJar(zf);
|
||||
engine.loadContract(c, cn, false);
|
||||
Map<String, byte[]> clzs = engine.dumpClass(); // 拿到的类和对应的字节码
|
||||
Map<String, MethodNode> methods = new HashMap<>();
|
||||
for (byte[] clz : clzs.values()) {
|
||||
ClassNode classNode = new ClassNode();
|
||||
ClassReader cr = new ClassReader(clz);
|
||||
cr.accept(classNode, ClassReader.EXPAND_FRAMES);
|
||||
for (MethodNode mn : classNode.methods) {
|
||||
methods.put(mn.name, mn);
|
||||
}
|
||||
}
|
||||
Map<String, String> result = new HashMap<>();
|
||||
for (FunctionNode fn : cn.getFunctions()) {
|
||||
MethodNode mn = methods.get(fn.functionName);
|
||||
if (mn != null && mn.name.equals("statAge")) {
|
||||
System.out.println("[ContractManager] verify:" + fn.functionName);
|
||||
TaintResult.nLocals = mn.maxLocals;
|
||||
TaintResult.nStack = mn.maxStack;
|
||||
TaintCFG cfg = new TaintCFG(mn);
|
||||
TaintResult.printer.setLabelOrder(cfg.getLabelOrder());
|
||||
FSAnalysis analysis = new FSAnalysis(cfg);
|
||||
analysis.analysis();
|
||||
TaintBB bb = cfg.getLastBlock();
|
||||
if (bb != null) result.put(fn.functionName, bb.getResult());
|
||||
cfg.printSelf();
|
||||
}
|
||||
}
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
5
src/main/java/org/bdware/sc/blockdb/Constants.java
Normal file
5
src/main/java/org/bdware/sc/blockdb/Constants.java
Normal file
@@ -0,0 +1,5 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
public class Constants {
|
||||
public static final int ELASTIC_DB = 0;
|
||||
}
|
||||
13
src/main/java/org/bdware/sc/blockdb/DBRepository.java
Normal file
13
src/main/java/org/bdware/sc/blockdb/DBRepository.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface DBRepository {
|
||||
public String Get(Map<String, Object> condition);//get hash of transaction
|
||||
public boolean Put(Transaction trans);//put transaction into databases
|
||||
public boolean Delete(String hash);//delete transaction
|
||||
public boolean Create_DB();//createDB
|
||||
public boolean Open_DB(); //OpenDB
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/blockdb/DBUtil.java
Normal file
12
src/main/java/org/bdware/sc/blockdb/DBUtil.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
public class DBUtil {
|
||||
private static DBRepository instance = null;
|
||||
|
||||
public static DBRepository getInstance(int type) {
|
||||
if (null == instance && type == Constants.ELASTIC_DB) {
|
||||
instance = new ElasticDBUtil();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
106
src/main/java/org/bdware/sc/blockdb/ElasticDBUtil.java
Normal file
106
src/main/java/org/bdware/sc/blockdb/ElasticDBUtil.java
Normal file
@@ -0,0 +1,106 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import okhttp3.*;
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ElasticDBUtil implements DBRepository {
|
||||
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
|
||||
public OkHttpClient client = new OkHttpClient();
|
||||
public List<Transaction> transactions = new ArrayList<>();
|
||||
public int bulk = 10000;
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
Map<String, Object> map1 = new HashMap<>();
|
||||
Map<String, String> map2 = new HashMap<>();
|
||||
map2.put("data", condition.get("data") + "*");
|
||||
map1.put("wildcard", map2);
|
||||
map.put("query", map1);
|
||||
String json = JsonUtil.toJson(map);
|
||||
RequestBody requestbody = FormBody.create(json, JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/_doc/_search").post(requestbody).build();
|
||||
try {
|
||||
Response resp = client.newCall(request).execute();
|
||||
System.out.print(resp.body().string());
|
||||
resp.body().close();
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return json;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
transactions.add(trans);
|
||||
if (transactions.size() == bulk) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try {
|
||||
for (int i = 0; i < bulk; i++) {
|
||||
sb
|
||||
.append("{\"index\":{}}\n{\"data\":\"")
|
||||
.append(new String(transactions.get(i).data, StandardCharsets.UTF_8))
|
||||
.append("\",")
|
||||
.append("\"hash\":")
|
||||
.append("\"")
|
||||
.append(new String(transactions.get(i).hash, StandardCharsets.UTF_8))
|
||||
.append("\"")
|
||||
.append("}")
|
||||
.append("\n");
|
||||
}
|
||||
//System.out.println(sb.toString());
|
||||
RequestBody requestbody = FormBody.create(sb.toString(), JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/_doc/_bulk").post(requestbody).build();
|
||||
Response res1 = client.newCall(request).execute();
|
||||
boolean res = res1.isSuccessful();
|
||||
res1.body().close();
|
||||
System.out.println(res);
|
||||
transactions.clear();
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
RequestBody body = RequestBody.create("", JSON);
|
||||
Request request = new Request.Builder().url("http://127.0.0.1:9200/transaction/").put(body).build();
|
||||
try {
|
||||
Response response = client.newCall(request).execute();
|
||||
boolean res = response.isSuccessful();
|
||||
response.body().close();
|
||||
return res;
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
}
|
||||
36
src/main/java/org/bdware/sc/blockdb/MongoDBUtil.java
Normal file
36
src/main/java/org/bdware/sc/blockdb/MongoDBUtil.java
Normal file
@@ -0,0 +1,36 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class MongoDBUtil {
|
||||
public static Object connect(String url, int port, String dbName, String usrName, String pwd) {
|
||||
try {
|
||||
Class serverAddr = Class.forName("com.mongodb.ServerAddress");
|
||||
Constructor cons = serverAddr.getConstructor(String.class, Integer.TYPE);
|
||||
Object serverAddress = cons.newInstance(url, port);
|
||||
List addrs = new ArrayList<>();
|
||||
addrs.add(serverAddress);
|
||||
Method createeScramSha1 =
|
||||
Class.forName("com.mongodb.MongoCredential")
|
||||
.getDeclaredMethod(
|
||||
"createScramSha1Credential",
|
||||
String.class,
|
||||
String.class,
|
||||
char[].class);
|
||||
Object credential = createeScramSha1.invoke(null, usrName, dbName, pwd.toCharArray());
|
||||
List credentials = new ArrayList<>();
|
||||
credentials.add(credential);
|
||||
Constructor mongoClient =
|
||||
Class.forName("com.mongodb.MongoClient").getConstructor(List.class, List.class);
|
||||
Object client = mongoClient.newInstance(addrs, credentials);
|
||||
// 通过连接认证获取MongoDB连接
|
||||
return client;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/main/java/org/bdware/sc/blockdb/RocksDBUtil.java
Normal file
72
src/main/java/org/bdware/sc/blockdb/RocksDBUtil.java
Normal file
@@ -0,0 +1,72 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
import org.rocksdb.Options;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.RocksDBException;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Map;
|
||||
|
||||
public class RocksDBUtil implements DBRepository{
|
||||
private static RocksDB rocksdb;
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
public static RocksDB loadDB(String path, String readOnly) {
|
||||
try {
|
||||
Options options = new Options();
|
||||
options.setCreateIfMissing(true);
|
||||
RocksDB rocksDB;
|
||||
File lockFile = new File(path,"LOCK");
|
||||
lockFile.delete();
|
||||
if (readOnly != null && readOnly.equals("true")) {
|
||||
rocksDB = RocksDB.openReadOnly(options, path);
|
||||
} else
|
||||
rocksDB = RocksDB.open(options, path);
|
||||
rocksdb = rocksDB;
|
||||
return rocksDB;
|
||||
|
||||
} catch (RocksDBException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
if(condition.containsKey("start")&&condition.containsKey("end")) {
|
||||
int start = (int)condition.get("start");
|
||||
int end = (int)condition.get("end");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
117
src/main/java/org/bdware/sc/blockdb/SqliteDBUtil.java
Normal file
117
src/main/java/org/bdware/sc/blockdb/SqliteDBUtil.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Block;
|
||||
import org.bdware.sc.commParser.BDLedger.BlockBody;
|
||||
import org.bdware.sc.commParser.BDLedger.BlockHeader;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.*;
|
||||
|
||||
public class SqliteDBUtil {
|
||||
private Connection conn;
|
||||
|
||||
public static SqliteDBUtil connect(String url) {
|
||||
try {
|
||||
String name = "org.sqlite.JDBC";
|
||||
SqliteDBUtil util = new SqliteDBUtil();
|
||||
String path = "jdbc:sqlite:";
|
||||
File file = new File(url);
|
||||
path = path + file.getAbsolutePath();
|
||||
System.out.println("[SqliteDBUtil] connect:" + path);
|
||||
Class.forName(name);
|
||||
util.conn = DriverManager.getConnection(path);
|
||||
return util;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public BlockBody getBlockBody(String headerHash, String bodyHash) {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockBody where ID = ?";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(bodyHash));
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
System.out.println(result.getBytes("ID"));
|
||||
return BlockBody.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public Block getBlock(String headerHash, String bodyHash) {
|
||||
try {
|
||||
BlockHeader header = new BlockHeader();
|
||||
BlockBody body = new BlockBody();
|
||||
Statement stmt = conn.createStatement();
|
||||
String sql = "select * from BlockBody where ID = ?";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(bodyHash));
|
||||
ResultSet result = pre.executeQuery();
|
||||
while (result.next()) {
|
||||
body = BlockBody.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
String sql1 = "select * from BlockHeader where Hash = ?";
|
||||
pre = conn.prepareStatement(sql1);
|
||||
pre.setBytes(1, HashUtil.str16ToBytes(headerHash));
|
||||
result = pre.executeQuery();
|
||||
while (result.next()) {
|
||||
header.index = result.getInt(1);
|
||||
header.hash = result.getBytes(2);
|
||||
header.version = result.getInt(3);
|
||||
header.timestamp = result.getInt(4);
|
||||
header.prevblockID = result.getBytes(5);
|
||||
header.merkleroot = result.getBytes(6);
|
||||
header.creatorID = result.getBytes(7);
|
||||
Block block = new Block(header,body);
|
||||
return block;
|
||||
//return Block.fromBytes(result.getBytes("Data"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte[] bodyselectall() {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockBody limit 1,1";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
return result.getBytes(1);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
public byte[] headerselectall() {
|
||||
try {
|
||||
Statement stmt = conn.createStatement();
|
||||
// ResultSet result = stmt.executeQuery("select * from BlockHeader where hash =
|
||||
// " + headerHash);
|
||||
String sql = "select * from BlockHeader limit 1,1";
|
||||
PreparedStatement pre = conn.prepareStatement(sql);
|
||||
ResultSet result = pre.executeQuery();
|
||||
// Assert we get only one!!!!
|
||||
while (result.next()) {
|
||||
return result.getBytes(2);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
39
src/main/java/org/bdware/sc/blockdb/TimeDBUtil.java
Normal file
39
src/main/java/org/bdware/sc/blockdb/TimeDBUtil.java
Normal file
@@ -0,0 +1,39 @@
|
||||
package org.bdware.sc.blockdb;
|
||||
|
||||
import org.bdware.sc.commParser.BDLedger.Transaction;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class TimeDBUtil implements DBRepository{
|
||||
|
||||
@Override
|
||||
public String Get(Map<String, Object> condition) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Put(Transaction trans) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Delete(String hash) {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Create_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean Open_DB() {
|
||||
// TODO Auto-generated method stub
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
200
src/main/java/org/bdware/sc/boundry/AccountIndex.java
Normal file
200
src/main/java/org/bdware/sc/boundry/AccountIndex.java
Normal file
@@ -0,0 +1,200 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.boundry.TimeIndex.Data;
|
||||
import org.bdware.sc.index.LenVarTimeSerialIndex2;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.objects.NativeArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class AccountIndex {
|
||||
static Map<String, LenVarTimeSerialIndex2> fileMap = new HashMap<>();
|
||||
|
||||
public static AccountIndex createIndex() {
|
||||
return new AccountIndex();
|
||||
}
|
||||
|
||||
private static String getString(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof String)) {
|
||||
return mem.toString();
|
||||
}
|
||||
return (String) mem;
|
||||
}
|
||||
|
||||
private static Integer getInteger(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Integer)) {
|
||||
return Integer.valueOf(mem.toString());
|
||||
}
|
||||
return (Integer) mem;
|
||||
}
|
||||
|
||||
private static Long getLong(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Long)) {
|
||||
return Long.valueOf(mem.toString());
|
||||
}
|
||||
return (Long) mem;
|
||||
}
|
||||
|
||||
public ScriptObject createFile(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("dataLength")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
Object file = args.get("file");
|
||||
if (!(file instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
Object address = args.get("account");
|
||||
if (!(address instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
String fileName = "./" + address + file;
|
||||
File f = new File(fileName + ".datasize");
|
||||
FileOutputStream fout = new FileOutputStream(f, false);
|
||||
Object dataLength = args.get("dataLength");
|
||||
int dataLengthInt = Integer.parseInt(dataLength.toString());
|
||||
for (int i = 0; i < dataLengthInt; i++)
|
||||
fout.write(1);
|
||||
fout.close();
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(fileName);
|
||||
ret.put("dataLength", dataLength, false);
|
||||
ret.put("datasize", f.length(), false);
|
||||
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("result", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject requestByTime(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("startTime")) {
|
||||
ret.put("result", "Missing Argumemt: startTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("endTime")) {
|
||||
ret.put("result", "Missing Argumemt: endTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "account") + getString(args, "file"));
|
||||
long startTime = getLong(args, "startTime");
|
||||
long endTime = getLong(args, "endTime");
|
||||
List<byte[]> result = index.requestByTime(startTime, endTime);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private LenVarTimeSerialIndex2 getIndexFile(String str) {
|
||||
LenVarTimeSerialIndex2 indexFile = fileMap.get(str);
|
||||
if (indexFile == null) {
|
||||
indexFile = new LenVarTimeSerialIndex2(str);
|
||||
fileMap.put(str, indexFile);
|
||||
}
|
||||
return indexFile;
|
||||
}
|
||||
|
||||
public ScriptObject manullyIndex(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("account")) {
|
||||
ret.put("result", "Missing Argumemt: account", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("date")) {
|
||||
ret.put("result", "Missing Argumemt: date", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "account") + getString(args, "file"));
|
||||
long date = getLong(args, "date");
|
||||
String content = getString(args, "content");
|
||||
index.manullyIndex(date, HashUtil.str16ToBytes(content));
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
742
src/main/java/org/bdware/sc/boundry/JavaScriptEntry.java
Normal file
742
src/main/java/org/bdware/sc/boundry/JavaScriptEntry.java
Normal file
@@ -0,0 +1,742 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.utils.SQLUtil;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.SocketGet;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.engine.SyncMechUtil;
|
||||
import org.bdware.sc.event.REvent;
|
||||
import org.bdware.sc.http.ApiGate;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.zz.gmhelper.SM2KeyPair;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.mail.*;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.security.Security;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static org.bdware.sc.event.REvent.REventType.*;
|
||||
|
||||
public class JavaScriptEntry {
|
||||
// private static final HostnameVerifier DO_NOT_VERIFY = (hostname, session) -> true;
|
||||
public static final Map<String, ScriptFunction> topic_handlers = new HashMap<>();
|
||||
private static final Logger LOGGER = LogManager.getLogger(JavaScriptEntry.class);
|
||||
public static NashornScriptEngine currentEngine;
|
||||
public static SyncMechUtil currentSyncUtil;
|
||||
// public static int contractManagerPort;
|
||||
public static Random random;
|
||||
public static long invokeID;
|
||||
public static String doi;
|
||||
public static String authInfoPersistDOI;
|
||||
public static SocketGet get; // public static CloseableHttpClient httpClient = getHttpClient();
|
||||
public static int numOfCopies;
|
||||
public static boolean isDebug;
|
||||
public static List<REvent> msgList;
|
||||
public static int shadingId;
|
||||
// private static SM2KeyPair keyPair = new SM2().generateKeyPair(); // TODO ?? 本地服务器的,39上运行39的
|
||||
// public static String privKey;
|
||||
// public static String pubKey;
|
||||
private static SM2KeyPair keyPair;
|
||||
|
||||
public static void setSM2KeyPair(String pubKey, String privKey) {
|
||||
keyPair =
|
||||
new SM2KeyPair(
|
||||
SM2KeyPair.publicKeyStr2ECPoint(pubKey), new BigInteger(privKey, 16));
|
||||
}
|
||||
|
||||
public static SM2KeyPair getKeyPair() {
|
||||
return keyPair;
|
||||
}
|
||||
|
||||
public static Global getEngineGlobal() {
|
||||
return currentEngine.getNashornGlobal();
|
||||
}
|
||||
|
||||
public static String byteArrayHash(byte[] hash) {
|
||||
return HashUtil.hashByteArray(hash);
|
||||
}
|
||||
|
||||
public static Connection getMysqlConnection(String url, String usrName, String pwd) {
|
||||
return SQLUtil.getConnection("jdbc:mysql://" + url, usrName, pwd);
|
||||
}
|
||||
|
||||
public static String example(String arg) {
|
||||
LOGGER.debug("called: " + arg);
|
||||
return arg + 1;
|
||||
}
|
||||
|
||||
// public static MongoClient connectMongoDb(String url, int port, String dbName, String usrName,
|
||||
// String pwd) {
|
||||
// return getMongoDBConnection(url, port, dbName, usrName, pwd);
|
||||
// }
|
||||
//
|
||||
// public static MongoClient getMongoDBConnection(String url, int port, String dbName, String
|
||||
// usrName, String pwd) {
|
||||
// return MongoDBUtil.connect(url, port, dbName, usrName, pwd);
|
||||
// }
|
||||
|
||||
public static String bytes2Str(byte[] bytes) {
|
||||
return new String(bytes);
|
||||
}
|
||||
|
||||
public static Object connectNeo4j(String url, String usrName, String pwd) {
|
||||
try {
|
||||
if (url.startsWith("jdbc:neo4j")) {
|
||||
Connection con;
|
||||
con = DriverManager.getConnection(url, usrName, pwd);
|
||||
return con;
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static long currentTimeMillis() {
|
||||
return System.currentTimeMillis();
|
||||
}
|
||||
|
||||
public static Lock createLock() {
|
||||
return new ReentrantLock();
|
||||
}
|
||||
|
||||
public static String asyncTest(String str, ScriptFunction fun) {
|
||||
LOGGER.debug(str);
|
||||
DesktopEngine.applyWithGlobal(fun, currentEngine.getNashornGlobal(), str);
|
||||
return "success";
|
||||
}
|
||||
|
||||
// public static String http(String baseUrl, String method, Map<String, String> header,
|
||||
// Map<String, String> argMap,
|
||||
// List<String> reservedList) {
|
||||
// return HttpUtil.request(baseUrl, method, header, argMap, reservedList);
|
||||
// }
|
||||
|
||||
public static byte[] inputStreamToBytes(InputStream in) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[4 * 1024 * 1024];
|
||||
try {
|
||||
for (int count; (count = in.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, count);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return bo.toByteArray();
|
||||
}
|
||||
|
||||
// private static String list2Str(List<String> reservedList) {
|
||||
// return JsonUtil.toJson(reservedList);
|
||||
// }
|
||||
//
|
||||
// private static String map2Str(Map<String, Object> map) {
|
||||
// return JsonUtil.toJson(map);
|
||||
// }
|
||||
|
||||
// private static CloseableHttpClient getHttpClient(String url) {
|
||||
// try {
|
||||
// SSLContext sslcontext = SSLContexts.custom().loadTrustMaterial(null, new TrustStrategy() {
|
||||
//
|
||||
// @Override
|
||||
// public boolean isTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
|
||||
// throws java.security.cert.CertificateException {
|
||||
// return true;
|
||||
// }
|
||||
// }).build();
|
||||
//
|
||||
// SSLConnectionSocketFactory sslSf = new SSLConnectionSocketFactory(sslcontext, null, null,
|
||||
// new NoopHostnameVerifier());
|
||||
// int tle = 10;
|
||||
// if (url.contains("data.tj.gov.cn"))
|
||||
// tle = 3;
|
||||
// return HttpClients.custom().setSSLSocketFactory(sslSf)
|
||||
// .setKeepAliveStrategy(new ConnectionKeepAliveStrategy() {
|
||||
// @Override
|
||||
// public long getKeepAliveDuration(HttpResponse arg0, HttpContext arg1) {
|
||||
// return 0;
|
||||
// }
|
||||
// }).setConnectionTimeToLive(tle, TimeUnit.SECONDS).build();
|
||||
//
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public static InputStream httpAsInputStream(String url) {
|
||||
try {
|
||||
URL realUrl = new URL(url);
|
||||
URLConnection conn = realUrl.openConnection();
|
||||
return conn.getInputStream();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// public static String httpPost(String str) {
|
||||
// System.out.println("JavaSScriptEntry httpPost:" + str);
|
||||
// PostRequest req = new PostRequest();
|
||||
// req = JsonUtil.fromJson(str, PostRequest.class);
|
||||
// // System.out.println("url========>" + req.url);
|
||||
// // System.out.println("data=======>" + req.data);
|
||||
//
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// URL url = new URL(req.url);//
|
||||
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// connection.setDoOutput(true);
|
||||
// connection.setDoInput(true);
|
||||
// connection.setUseCaches(false);
|
||||
// connection.setInstanceFollowRedirects(true);
|
||||
// connection.setRequestMethod("POST"); // 璁剧疆璇锋眰鏂瑰紡
|
||||
// connection.setRequestProperty("Accept", "application/json"); // 璁剧疆鎺ユ敹鏁版嵁鐨勬牸寮<E789B8>
|
||||
// connection.setRequestProperty("Content-Type", "application/json"); // 璁剧疆鍙戦<E98D99>佹暟鎹殑鏍煎紡
|
||||
// connection.connect();
|
||||
// OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); //
|
||||
// utf-8缂栫爜
|
||||
// out.append(req.data);
|
||||
// out.flush();
|
||||
// out.close();
|
||||
//
|
||||
// r.resposeCode = connection.getResponseCode();
|
||||
// InputStream input = connection.getInputStream();
|
||||
//
|
||||
// Scanner sc = new Scanner(input);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (; sc.hasNextLine();) {
|
||||
// sb.append(sc.nextLine()).append("\n");
|
||||
// }
|
||||
// sc.close();
|
||||
// r.response = sb.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static void executeFunction(ScriptFunction callback, Object arg) {
|
||||
DesktopEngine.applyWithGlobal(callback, currentEngine.getNashornGlobal(), arg);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip) {
|
||||
return new ApiGate(ip);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip, String port) {
|
||||
return new ApiGate(ip, Integer.parseInt(port));
|
||||
}
|
||||
|
||||
public static String executeContractWithSig(
|
||||
String contractID, String action, String arg, String pubkey, String sig) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setPublicKey(pubkey);
|
||||
app.setSignature(sig);
|
||||
app.fromContract = keyPair.getPublicKeyStr();
|
||||
if (!app.verifySignature()) {
|
||||
return "{\"status\":\"Exception\",\"data\":\"invalid signature\"}";
|
||||
}
|
||||
app.setRequesterDOI(doi);
|
||||
app.setFromDebug(isDebug);
|
||||
if (numOfCopies > 1) {
|
||||
// The caller is special.
|
||||
app.setRequestID(
|
||||
app.getPublicKey().hashCode()
|
||||
+ "_"
|
||||
+ numOfCopies
|
||||
+ "_"
|
||||
+ (invokeID++)
|
||||
+ "_"
|
||||
+ random.nextInt()
|
||||
+ "_mul");
|
||||
} else {
|
||||
app.setRequestID(
|
||||
app.getPublicKey().hashCode()
|
||||
+ "_"
|
||||
+ (invokeID++)
|
||||
+ "_"
|
||||
+ random.nextInt());
|
||||
}
|
||||
return get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
|
||||
public static String executeContract(String contractID, String action, String arg) {
|
||||
if (currentSyncUtil.engine.recovering) {
|
||||
String str =
|
||||
currentSyncUtil.transRecoverUtil.curRecoverRecord.getExecuteResult(
|
||||
invokeID + "");
|
||||
String[] strs = str.split("<seperate>");
|
||||
String flag1 = strs[0];
|
||||
String flag = strs[1];
|
||||
String res = strs[2];
|
||||
if (flag1.equals("1")) {
|
||||
invokeID++;
|
||||
}
|
||||
if (flag.equals("1")) {
|
||||
random.nextInt();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
long formerInvokeID = invokeID;
|
||||
int flag1 = 0; // 标志invokeID++操作是否进行过
|
||||
int flag = 0; // 标志random是否取下一个
|
||||
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(keyPair);
|
||||
app.setRequesterDOI(doi);
|
||||
app.setFromDebug(isDebug);
|
||||
if (numOfCopies > 1) {
|
||||
app.setRequestID(
|
||||
String.format(
|
||||
"%d_%d_%d_%d_mul",
|
||||
keyPair.getPublicKeyStr().hashCode(),
|
||||
numOfCopies,
|
||||
(invokeID++),
|
||||
random.nextInt()));
|
||||
// The caller is special.
|
||||
flag = 1;
|
||||
flag1 = 1;
|
||||
LOGGER.warn("invoke contractExecution! " + JsonUtil.toJson(app));
|
||||
} else {
|
||||
app.setRequestID(
|
||||
String.format(
|
||||
"%d_%d_%d",
|
||||
keyPair.getPublicKeyStr().hashCode(),
|
||||
(invokeID++),
|
||||
random.nextInt()));
|
||||
flag = 1;
|
||||
flag1 = 1;
|
||||
}
|
||||
return executeContract(formerInvokeID, flag1, flag, app);
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
String result = bo.toString();
|
||||
if (currentSyncUtil.startFlag
|
||||
&& currentSyncUtil.currType == SyncType.Trans
|
||||
&& !currentSyncUtil.engine.recovering) {
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(
|
||||
formerInvokeID + "", flag1 + "<seperate>" + flag + "<seperate>" + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
private static String executeContract(long formerInvokeID, int flag1, int flag, ContractRequest app) {
|
||||
String result = get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
if (currentSyncUtil.startFlag
|
||||
&& currentSyncUtil.currType == SyncType.Trans
|
||||
&& !currentSyncUtil.engine.recovering) {
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(
|
||||
formerInvokeID + "",
|
||||
flag1 + "<seperate>" + flag + "<seperate>" + result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void executeContractAsyncWithoutSig(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setRequestID((invokeID++) + "_" + random.nextInt());
|
||||
get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (null != cb) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, currentEngine.getNashornGlobal(), str);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
}
|
||||
}
|
||||
|
||||
/* public static String executeContract(String contractID, String action, String arg) {
|
||||
//redo,use record data
|
||||
if(currentSyncUtil.transRecoverUtil != null && currentSyncUtil.transRecoverUtil.recovering){
|
||||
String k = TransRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
return currentSyncUtil.transRecoverUtil.curRecoverRecord.getExecuteResult(k);
|
||||
}
|
||||
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
//app.doSignature(keyPair.getPrivateKey().toString(16));
|
||||
app.doSignature(keyPair);
|
||||
String result = get.syncGet("dd", "executeContract", JsonUtil.toJson(app));
|
||||
if(currentSyncUtil.startFlag && currentSyncUtil.currType == SyncType.Trans){
|
||||
String k = currentSyncUtil.transRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(k,result);
|
||||
}
|
||||
return result;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
String result = bo.toString();
|
||||
if(currentSyncUtil.startFlag && currentSyncUtil.currType == SyncType.Trans){
|
||||
String k = TransRecordUtil.produceExecuteIdentifier(contractID,action,arg);
|
||||
currentSyncUtil.transRecordUtil.recordExecutes(k,result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}*/
|
||||
|
||||
// public static String queryContractIdByDOI(String contractDOI) throws Exception {
|
||||
// DigitalObject contractDO;
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.retrieve(contractDOI, null, null);
|
||||
// if (response.parameters.response == DoResponse.Success) {
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// } else {
|
||||
// response = DOAClient.getGlobalInstance().retrieve(contractDOI, null, null);
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// }
|
||||
// ContractInstanceDO contractInstanceDO =
|
||||
// (ContractInstanceDO)
|
||||
// ContractManager.toObject(contractDO.elements.get(0).getData());
|
||||
// return contractInstanceDO.id;
|
||||
// }
|
||||
|
||||
// public static String executeContractByDOI(String contractDOI, String action, String arg) {
|
||||
// try {
|
||||
// String contractID = queryContractIdByDOI(contractDOI);
|
||||
// return executeContract(contractID, action, arg);
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return bo.toString();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static String getAuthInfo() {
|
||||
// try {
|
||||
// DigitalObject contractDO;
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.retrieve(authInfoPersistDOI, null, null);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// response = DOAClient.getGlobalInstance().retrieve(authInfoPersistDOI, null,
|
||||
// null);
|
||||
// }
|
||||
// contractDO = DigitalObject.parse(response.body);
|
||||
// return new String(contractDO.elements.get(0).getData());
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return "Failed: " + bo.toString();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// public static String setAuthInfo(String authInfo) {
|
||||
// try {
|
||||
//
|
||||
// DigitalObject contractDO = new DigitalObject(authInfoPersistDOI, DoType.Json);
|
||||
// Element e = new Element("authInfo", "JsonString");
|
||||
// e.setData(authInfo.getBytes());
|
||||
// contractDO.addElements(e);
|
||||
//
|
||||
// DoipClient doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// DOIPMainServer.repoUrl, DoipMessageFormat.PACKET.getName());
|
||||
// DoMessage response = doipClient.update(contractDO);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// DoHandleRecord dohr =
|
||||
// DOAClient.getGlobalInstance().resolveDO(authInfoPersistDOI);
|
||||
// if (dohr == null) {
|
||||
// return "Failed: Can not resolve authInfoPersistDOI: " +
|
||||
// authInfoPersistDOI;
|
||||
// }
|
||||
// ServiceHandleRecord repoHandleRecord =
|
||||
// DOAClient.getGlobalInstance().resolveDOIPService(dohr.repository);
|
||||
// doipClient =
|
||||
// DoipClient.createByRepoUrlAndMsgFmt(
|
||||
// repoHandleRecord.getListenerInfos().get(0).url,
|
||||
// DoipMessageFormat.PACKET.getName());
|
||||
// response = doipClient.update(contractDO);
|
||||
// if (response.parameters.response != DoResponse.Success) {
|
||||
// return "Failed: Can not update authInfoPersistDOI: " + authInfoPersistDOI;
|
||||
// }
|
||||
// }
|
||||
// return "Succeeded";
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// return "Failed: " + bo.toString();
|
||||
// }
|
||||
// }
|
||||
|
||||
public static String executeContractAsync(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(keyPair);
|
||||
app.setRequestID((invokeID++) + "_" + random());
|
||||
app.setRequesterDOI(doi);
|
||||
get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (cb != null) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, currentEngine.getNashornGlobal(), str, arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* publish an event with semantic AT_LEAST_ONCE
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void pubEvent(String topic, String content) {
|
||||
pubEventConstraint(topic, content, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* publish an event with some semantic
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @param constraint the constraint, AT_LEAST_ONCE, AT_MOST_ONCE, and ONLY_ONCE
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void pubEventConstraint(String topic, String content, String constraint) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_pe",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
REvent msg = new REvent(topic, PUBLISH, content, reqID);
|
||||
if (null != constraint) {
|
||||
msg.setSemantics(REvent.REventSemantics.valueOf(constraint));
|
||||
}
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* subscribe a topic
|
||||
*
|
||||
* @param topic event topic
|
||||
* @param fun related handler function
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void subscribe(String topic, ScriptFunction fun) {
|
||||
subscribe(topic, fun, false);
|
||||
if (topic_handlers.containsKey(topic)) {
|
||||
ContractProcess.instance.unSubscribe(topic_handlers.get(topic).getName());
|
||||
}
|
||||
topic_handlers.put(topic, fun);
|
||||
}
|
||||
|
||||
private static void subscribe(String topic, ScriptFunction fun, boolean fromPreSub) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_se",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
|
||||
REvent msg =
|
||||
new REvent(
|
||||
topic,
|
||||
SUBSCRIBE,
|
||||
String.format(
|
||||
"{\"subscriber\":\"%s\",\"handler\":\"%s\"}",
|
||||
ContractProcess.instance.getContractName(), fun.getName()),
|
||||
reqID);
|
||||
if (fromPreSub) {
|
||||
msg.setSemantics(REvent.REventSemantics.ONLY_ONCE);
|
||||
}
|
||||
msgList.add(msg);
|
||||
|
||||
ContractProcess.instance.subscribe(fun.getName());
|
||||
}
|
||||
|
||||
public static void unsubscribe(String topic) {
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_us",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, invokeID, random());
|
||||
String content;
|
||||
if (null == topic) {
|
||||
content = "{\"subscriber\":\"" + ContractProcess.instance.getContractName() + "\"}";
|
||||
topic_handlers.forEach((k, c) -> {
|
||||
topic_handlers.remove(k);
|
||||
ContractProcess.instance.unSubscribe(c.getName());
|
||||
});
|
||||
} else {
|
||||
String handler = topic_handlers.get(topic).getName();
|
||||
content =
|
||||
String.format(
|
||||
"{\"subscriber\":\"%s\",\"handler\":\"%s\"}",
|
||||
ContractProcess.instance.getContractName(), handler);
|
||||
topic_handlers.remove(topic);
|
||||
ContractProcess.instance.unSubscribe(handler);
|
||||
}
|
||||
REvent msg =
|
||||
new REvent(
|
||||
topic,
|
||||
UNSUBSCRIBE,
|
||||
content,
|
||||
reqID);
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* pre-sub in ONLY_ONCE
|
||||
*
|
||||
* @param topic the topic
|
||||
* @param content the content
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static void preSub(String topic, String content) {
|
||||
String newTopic = topic + "|" + content + "|" + ContractProcess.instance.getContractName();
|
||||
subscribe(newTopic, topic_handlers.get(topic), true);
|
||||
String reqID =
|
||||
String.format(
|
||||
"%d_%d_%d_%s_pse",
|
||||
keyPair.getPublicKeyStr().hashCode(), numOfCopies, (invokeID++), random());
|
||||
REvent msg = new REvent(topic, REvent.REventType.PRESUB, newTopic, reqID);
|
||||
msg.setSemantics(REvent.REventSemantics.ONLY_ONCE);
|
||||
msgList.add(msg);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a random value with string format
|
||||
* @author Kaidong Wu
|
||||
*/
|
||||
public static String random() {
|
||||
String seed = String.valueOf(null == random ? System.currentTimeMillis() : random.nextInt());
|
||||
return HashUtil.sha3(seed);
|
||||
}
|
||||
|
||||
public static String getContractInfo(String topic) {
|
||||
return null;
|
||||
// TODO
|
||||
}
|
||||
|
||||
public static String sendEmail(String json) {
|
||||
try {
|
||||
final JsonObject jo = JsonParser.parseString(json).getAsJsonObject();
|
||||
Properties props = new Properties();
|
||||
props.setProperty("mail.debug", "false");
|
||||
props.setProperty("mail.smtp.auth", "true");
|
||||
props.setProperty("mail.smtp.host", jo.get("host").getAsString());
|
||||
props.setProperty("mail.smtp.port", jo.get("port").getAsString());
|
||||
props.setProperty("mail.transport.protocol", "smtp");
|
||||
props.put("mail.smtp.auth", "true");
|
||||
Security.addProvider(new com.sun.net.ssl.internal.ssl.Provider());
|
||||
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory";
|
||||
props.setProperty("mail.smtp.socketFactory.class", SSL_FACTORY);
|
||||
props.setProperty("mail.smtp.socketFactory.fallback", "false");
|
||||
props.setProperty("mail.smtp.socketFactory.port", jo.get("port").getAsString());
|
||||
Session session =
|
||||
Session.getDefaultInstance(
|
||||
props,
|
||||
new Authenticator() {
|
||||
public PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(
|
||||
jo.get("from").getAsString(),
|
||||
jo.get("pwd").getAsString()); // 发件人邮件用户名、密码
|
||||
}
|
||||
});
|
||||
// 创建邮件对象
|
||||
|
||||
Message msg = new MimeMessage(session);
|
||||
msg.setSubject(jo.get("subject").getAsString());
|
||||
msg.setText(jo.get("content").getAsString());
|
||||
msg.setFrom(new InternetAddress(jo.get("from").getAsString()));
|
||||
msg.addRecipient(
|
||||
Message.RecipientType.TO, new InternetAddress(jo.get("to").getAsString()));
|
||||
Transport.send(msg);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return "failed";
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static ScriptObject getCaller(int i) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
|
||||
if (stacktrace.length > i + 2) {
|
||||
ret.put("name", stacktrace[i + 2].getMethodName(), false);
|
||||
ret.put("file", stacktrace[i + 2].getFileName(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
public int responseCode;
|
||||
public String response;
|
||||
}
|
||||
|
||||
static class PostRequest {
|
||||
String url;
|
||||
String data;
|
||||
}
|
||||
}
|
||||
93
src/main/java/org/bdware/sc/boundry/Resources.java
Normal file
93
src/main/java/org/bdware/sc/boundry/Resources.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.engine.YJSClassLoader;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Scanner;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import java.util.zip.ZipInputStream;
|
||||
public class Resources {
|
||||
private final ZipFile zf;
|
||||
YJSClassLoader loader;
|
||||
|
||||
public Resources(ZipFile zf, YJSClassLoader loader) {
|
||||
this.zf = zf;
|
||||
this.loader = loader;
|
||||
}
|
||||
|
||||
public InputStream loadAsInputStream(String path) {
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
return zf.getInputStream(entry);
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Scanner loadAsScanner(String path) {
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
return new Scanner(zf.getInputStream(entry));
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String loadAsString(String path) {
|
||||
try {
|
||||
InputStream sc = loadAsInputStream(path);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[1024];
|
||||
for (int k = 0; (k = sc.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, k);
|
||||
}
|
||||
return new String(bo.toByteArray());
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<?> testloadAsScanner(String path) {
|
||||
BufferedReader reader;
|
||||
List<String> fileList = new ArrayList<>();
|
||||
try {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
if (entry == null)
|
||||
return null;
|
||||
reader = new BufferedReader(new InputStreamReader(zf.getInputStream(entry), StandardCharsets.UTF_8));
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
fileList.add(line);
|
||||
// System.out.println(line);
|
||||
}
|
||||
return fileList;
|
||||
// return new ArrayList<>();
|
||||
} catch (Exception ignored) {
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String unzipToDir(String path) {
|
||||
ZipEntry entry = zf.getEntry(path);
|
||||
try {
|
||||
return loader.unzipLibrary(zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
306
src/main/java/org/bdware/sc/boundry/TimeIndex.java
Normal file
306
src/main/java/org/bdware/sc/boundry/TimeIndex.java
Normal file
@@ -0,0 +1,306 @@
|
||||
package org.bdware.sc.boundry;
|
||||
|
||||
import org.bdware.sc.index.LenVarTimeSerialIndex2;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.objects.NativeArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TimeIndex {
|
||||
static Map<String, LenVarTimeSerialIndex2> fileMap = new HashMap<>();
|
||||
|
||||
public static TimeIndex createIndex() {
|
||||
return new TimeIndex();
|
||||
}
|
||||
|
||||
private static String getString(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof String)) {
|
||||
return mem.toString();
|
||||
}
|
||||
return (String) mem;
|
||||
}
|
||||
|
||||
private static Integer getInteger(ScriptObjectMirror obj) {
|
||||
Object mem = obj.getMember("count");
|
||||
if (mem != null && !(mem instanceof Integer)) {
|
||||
return Integer.valueOf(mem.toString());
|
||||
}
|
||||
return (Integer) mem;
|
||||
}
|
||||
|
||||
private static Long getLong(ScriptObjectMirror obj, String member) {
|
||||
Object mem = obj.getMember(member);
|
||||
if (mem != null && !(mem instanceof Long)) {
|
||||
return Long.valueOf(mem.toString());
|
||||
}
|
||||
return (Long) mem;
|
||||
}
|
||||
|
||||
public ScriptObject createFile(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("dataLength")) {
|
||||
ret.put("result", "Missing Argumemt", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
Object file = args.get("file");
|
||||
if (!(file instanceof String)) {
|
||||
ret.put("result", "Illegal Type, file is not String", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
String fileName = "./" + file;
|
||||
File f = new File(fileName + ".datasize");
|
||||
FileOutputStream fout = new FileOutputStream(f, false);
|
||||
Object dataLength = args.get("dataLength");
|
||||
int dataLengthInt = Integer.parseInt(dataLength.toString());
|
||||
for (int i = 0; i < dataLengthInt; i++)
|
||||
fout.write(1);
|
||||
fout.close();
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(fileName);
|
||||
ret.put("dataLength", dataLength, false);
|
||||
ret.put("datasize", f.length(), false);
|
||||
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("result", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject index(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
String content = getString(args, "content");
|
||||
long result = index.index(HashUtil.str16ToBytes(content));
|
||||
ret.put("date", result, false);
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("exception", bo.toString(), false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject dataSize(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
ret.put("fileSize", index.fileSize, false);
|
||||
ret.put("dataSize", index.dataSize, false);
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("exception", bo.toString(), false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject requestByTime(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("startTime")) {
|
||||
ret.put("result", "Missing Argumemt: startTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("endTime")) {
|
||||
ret.put("result", "Missing Argumemt: endTime", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long startTime = getLong(args, "startTime");
|
||||
long endTime = getLong(args, "endTime");
|
||||
List<byte[]> result = index.requestByTime(startTime, endTime);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject request(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("offset")) {
|
||||
ret.put("result", "Missing Argumemt: offset", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("count")) {
|
||||
ret.put("result", "Missing Argumemt: count", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long offset = getLong(args, "offset");
|
||||
int count = getInteger(args);
|
||||
List<byte[]> result = index.request(offset, count);
|
||||
ret.put("status", "Success", false);
|
||||
NativeArray array = Global.allocate(new int[0]);
|
||||
ret.put("list", array, false);
|
||||
for (byte[] bytes : result) {
|
||||
JO data = new JO(PropertyMap.newMap());
|
||||
Data d = new Data(bytes);
|
||||
data.put("data", d.data, false);
|
||||
data.put("date", d.date, false);
|
||||
NativeArray.push(array, data);
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObject getSize(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
int size = (int) index.size();
|
||||
ret.put("status", "Success", false);
|
||||
ret.put("size", size, false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
private LenVarTimeSerialIndex2 getIndexFile(String str) {
|
||||
LenVarTimeSerialIndex2 indexFile = fileMap.get(str);
|
||||
if (indexFile == null) {
|
||||
indexFile = new LenVarTimeSerialIndex2(str);
|
||||
fileMap.put(str, indexFile);
|
||||
}
|
||||
return indexFile;
|
||||
}
|
||||
|
||||
public ScriptObject manuallyIndex(ScriptObjectMirror args) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
if (!args.hasMember("date")) {
|
||||
ret.put("result", "Missing Argumemt: date", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("content")) {
|
||||
ret.put("result", "Missing Argumemt: content", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
if (!args.hasMember("file")) {
|
||||
ret.put("result", "Missing Argumemt: file", false);
|
||||
ret.put("status", "Error", false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
try {
|
||||
LenVarTimeSerialIndex2 index = getIndexFile(getString(args, "file"));
|
||||
long date = getLong(args, "date");
|
||||
String content = getString(args, "content");
|
||||
index.manullyIndex(date, HashUtil.str16ToBytes(content));
|
||||
ret.put("status", "Success", false);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("status", "Error", false);
|
||||
ret.put("data", bo.toString(), false);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
static class Data {
|
||||
long date;
|
||||
String data;
|
||||
|
||||
public Data(byte[] bytes) {
|
||||
date = HashUtil.bytes2Long(bytes);
|
||||
data = HashUtil.byteArray2Str(bytes, 8);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
50
src/main/java/org/bdware/sc/boundry/utils/AESUtil.java
Normal file
50
src/main/java/org/bdware/sc/boundry/utils/AESUtil.java
Normal file
@@ -0,0 +1,50 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import javax.xml.bind.DatatypeConverter;
|
||||
import java.security.InvalidAlgorithmParameterException;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
@PermissionStub(permission = Permission.AES)
|
||||
public class AESUtil {
|
||||
public static ScriptObject encrypt(String key, String plaintext) throws NoSuchPaddingException, NoSuchAlgorithmException, BadPaddingException, IllegalBlockSizeException, InvalidAlgorithmParameterException, InvalidKeyException {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
String iv = generateKey(128);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(DatatypeConverter.parseHexBinary(iv));
|
||||
byte[] byteContent = plaintext.getBytes();
|
||||
SecretKeySpec secretKeySpecSpec = new SecretKeySpec(DatatypeConverter.parseHexBinary(key), "AES");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpecSpec, ivSpec);
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
ret.put("iv", iv, false);
|
||||
ret.put("cipherText", DatatypeConverter.printHexBinary(result).toLowerCase(), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String decrypt(String key, String ciphertext, String iv) throws NoSuchPaddingException, NoSuchAlgorithmException, InvalidAlgorithmParameterException, InvalidKeyException, BadPaddingException, IllegalBlockSizeException {
|
||||
// JO ret = new JO(PropertyMap.newMap());
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(DatatypeConverter.parseHexBinary(iv));
|
||||
byte[] byteContent = DatatypeConverter.parseHexBinary(ciphertext);
|
||||
SecretKeySpec secretKeySpecSpec = new SecretKeySpec(DatatypeConverter.parseHexBinary(key), "AES");
|
||||
cipher.init(Cipher.DECRYPT_MODE, secretKeySpecSpec, ivSpec);
|
||||
byte[] result = cipher.doFinal(byteContent);
|
||||
return new String(result);
|
||||
}
|
||||
|
||||
public static String generateKey(int bit) throws NoSuchAlgorithmException {
|
||||
KeyGenerator keyGenerator = KeyGenerator.getInstance("AES");
|
||||
keyGenerator.init(bit);
|
||||
SecretKey secretKey = keyGenerator.generateKey();
|
||||
return DatatypeConverter.printHexBinary(secretKey.getEncoded()).toLowerCase();
|
||||
}
|
||||
}
|
||||
117
src/main/java/org/bdware/sc/boundry/utils/AsyncUtil.java
Normal file
117
src/main/java/org/bdware/sc/boundry/utils/AsyncUtil.java
Normal file
@@ -0,0 +1,117 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.ServiceServer;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
@PermissionStub(permission = Permission.Async)
|
||||
public class AsyncUtil {
|
||||
private static final Timer TIMER = new Timer();
|
||||
// public static ExecutorService executorService = Executors.newFixedThreadPool(10);
|
||||
|
||||
public static String sleep(long sleep) {
|
||||
try {
|
||||
Thread.sleep(sleep);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static String postFunction(final ScriptFunction callback, Object wrapper) {
|
||||
ServiceServer.executor.execute(
|
||||
() -> JavaScriptEntry.executeFunction(callback, wrapper));
|
||||
return "success";
|
||||
}
|
||||
|
||||
public static TimerTask setTimeOut(
|
||||
final ScriptFunction callback, long delay, final Object arg) {
|
||||
TimerTask task =
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
JavaScriptEntry.executeFunction(callback, arg);
|
||||
}
|
||||
};
|
||||
TIMER.schedule(task, delay);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static TimerTask setInterval(
|
||||
final ScriptFunction callback, long delay, long interval, final Object arg) {
|
||||
TimerTask task =
|
||||
new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
JavaScriptEntry.executeFunction(callback, arg);
|
||||
}
|
||||
};
|
||||
TIMER.schedule(task, delay, interval);
|
||||
return task;
|
||||
}
|
||||
|
||||
public static void executeContractAsyncWithoutSig(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.setRequestID((JavaScriptEntry.invokeID++) + "_" + JavaScriptEntry.random.nextInt());
|
||||
JavaScriptEntry.get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (null != cb) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, JavaScriptEntry.currentEngine.getNashornGlobal(), str);
|
||||
}
|
||||
}
|
||||
});
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
}
|
||||
}
|
||||
public static String executeContractAsync(
|
||||
String contractID, String action, String arg, final ScriptFunction cb) {
|
||||
try {
|
||||
|
||||
ContractRequest app = new ContractRequest();
|
||||
app.setContractID(contractID).setAction(action).setArg(arg);
|
||||
app.doSignature(JavaScriptEntry.getKeyPair());
|
||||
app.setRequestID((JavaScriptEntry.invokeID++) + "_" + JavaScriptEntry.random());
|
||||
app.setRequesterDOI(JavaScriptEntry.doi);
|
||||
JavaScriptEntry.get.asyncGet(
|
||||
"dd",
|
||||
"executeContract",
|
||||
JsonUtil.toJson(app),
|
||||
new ResultCallback() {
|
||||
@Override
|
||||
public void onResult(String str) {
|
||||
if (cb != null) {
|
||||
DesktopEngine.applyWithGlobal(
|
||||
cb, JavaScriptEntry.currentEngine.getNashornGlobal(), str, arg);
|
||||
}
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
return bo.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.db.TimeDBUtil;
|
||||
import org.bdware.sc.db.TimeRocksDBUtil;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@PermissionStub(permission = Permission.BDWareTimeSeriesDB)
|
||||
public class BDWareTimeSeriesDBUtil {
|
||||
public static TimeRocksDBUtil getConnection() {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
parent = new File(parent, "BDWareTimeSeriesDB");
|
||||
return new TimeRocksDBUtil(parent.getAbsolutePath());
|
||||
}
|
||||
|
||||
public static TimeRocksDBUtil getConnection(String dbName) {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
parent = new File(parent, dbName);
|
||||
return new TimeRocksDBUtil(parent.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/boundry/utils/CMUtil.java
Normal file
12
src/main/java/org/bdware/sc/boundry/utils/CMUtil.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
@PermissionStub(permission = Permission.CM)
|
||||
public class CMUtil {
|
||||
public static String getTimesOfExecution(String contractName) {
|
||||
return JavaScriptEntry.get.syncGet("", "getTimesOfExecution", contractName);
|
||||
}
|
||||
}
|
||||
192
src/main/java/org/bdware/sc/boundry/utils/DOIPUtil.java
Normal file
192
src/main/java/org/bdware/sc/boundry/utils/DOIPUtil.java
Normal file
@@ -0,0 +1,192 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bdware.doip.application.client.ContractDOAClient;
|
||||
import org.bdware.doip.core.doipMessage.DoipMessage;
|
||||
import org.bdware.doip.core.exception.DoDecodeException;
|
||||
import org.bdware.doip.core.exception.IrpClientException;
|
||||
import org.bdware.doip.core.model.digitalObject.DigitalObject;
|
||||
import org.bdware.doip.core.model.digitalObject.Element;
|
||||
import org.bdware.doip.core.utils.DoipGson;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@PermissionStub(permission = Permission.DOIP)
|
||||
public class DOIPUtil {
|
||||
// private static final Logger LOGGER = LogManager.getLogger(DOIPUtil.class);
|
||||
public static ContractDOAClient doaClient = null;
|
||||
|
||||
static {
|
||||
initClient();
|
||||
}
|
||||
|
||||
public static String test(String doi) {
|
||||
return "create DOClient And hello " + doi + " World";
|
||||
}
|
||||
|
||||
public static String hello(String repoID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.hello(repoID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String retrieve(String doi, String args) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
JsonObject argObj = JsonUtil.fromJson(args, JsonObject.class);
|
||||
String elementID = argObj.get("elementID") == null ? null : argObj.get("elementID").getAsString();
|
||||
boolean includeElementData =
|
||||
argObj.get("includeElementData") != null &&
|
||||
argObj.get("includeElementData").getAsString().equals("true");
|
||||
try {
|
||||
msg = doaClient.retrieve(doi, elementID, includeElementData);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String call(String doi, String action, String args) {
|
||||
initClient();
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.call(doi, action, args.getBytes());
|
||||
return msg.body.getDataAsJsonString();
|
||||
} catch (IrpClientException e) {
|
||||
e.printStackTrace();
|
||||
return e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
public static String create(String repoID, String doString) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
DigitalObject dObj = DoipGson.getDoipGson().fromJson(doString, DigitalObject.class);
|
||||
for (Element e : dObj.elements) {
|
||||
if (null != e.dataString) {
|
||||
e.setData(e.dataString.getBytes());
|
||||
}
|
||||
e.dataString = null;
|
||||
}
|
||||
try {
|
||||
msg = doaClient.create(repoID, dObj);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String delete(String doID, String repoID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.delete(doID, repoID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
public static String listOperation(String doID) {
|
||||
initClient();
|
||||
DigitalObject respDO;
|
||||
DoipMessage msg;
|
||||
try {
|
||||
msg = doaClient.listOperations(doID);
|
||||
} catch (IrpClientException ie) {
|
||||
ie.printStackTrace();
|
||||
return "send doip message error: " + ie.getMessage();
|
||||
}
|
||||
try {
|
||||
respDO = msg.body.getDataAsDigitalObject();
|
||||
return respDO.toString();
|
||||
} catch (DoDecodeException | IOException e) {
|
||||
e.printStackTrace();
|
||||
return new String(msg.body.getEncodedData());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// public static String create(String repoID, ScriptObjectMirror doStr){
|
||||
// logger.debug(JsonUtil.toJson(doStr));
|
||||
// SM2KeyPair kp = JavaScriptEntry.getKeyPair();
|
||||
// HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
|
||||
// DOAClient client = DOAClient.getGlobalInstance();
|
||||
// logger.debug(JsonUtil.toJson(doStr));
|
||||
// DigitalObject digitalObject = new DigitalObject(
|
||||
// doStr.get("doID").toString(),
|
||||
// DoType.DoString
|
||||
// );
|
||||
// digitalObject.addAttribute("content", doStr.get("doBody").toString());
|
||||
// try {
|
||||
// return new String(client.create(repoID,digitalObject).parameters.toByteArray());
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return e.getMessage();
|
||||
// }
|
||||
// }
|
||||
|
||||
// public static String update(ScriptObjectMirror doStr){
|
||||
// SM2KeyPair kp = JavaScriptEntry.getKeyPair();
|
||||
// HandleServiceUtils.CustomizeHandleService(kp,JavaScriptEntry.doi,HandleServiceUtils.LHS_Address);
|
||||
// DOAClient client = DOAClient.getGlobalInstance();
|
||||
// DigitalObject digitalObject = new DigitalObject(
|
||||
// doStr.get("doID").toString(),
|
||||
// DoType.DoString
|
||||
// );
|
||||
// digitalObject.addAttribute("content", doStr.get("doBody").toString());
|
||||
// try {
|
||||
// return new String(client.update(digitalObject).parameters.toByteArray());
|
||||
// }catch (Exception e){
|
||||
// e.printStackTrace();
|
||||
// return e.getMessage();
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
public static void initClient() {
|
||||
if (null == doaClient) {
|
||||
doaClient = ContractDOAClient.getContractDOAClientForTest();
|
||||
}
|
||||
}
|
||||
}
|
||||
10
src/main/java/org/bdware/sc/boundry/utils/DOMUtil.java
Normal file
10
src/main/java/org/bdware/sc/boundry/utils/DOMUtil.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
import org.jsoup.nodes.Document;
|
||||
|
||||
public class DOMUtil {
|
||||
public static Document parse(String html) {
|
||||
return Jsoup.parse(html);
|
||||
}
|
||||
}
|
||||
42
src/main/java/org/bdware/sc/boundry/utils/FileUtil.java
Normal file
42
src/main/java/org/bdware/sc/boundry/utils/FileUtil.java
Normal file
@@ -0,0 +1,42 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
import java.io.File;
|
||||
import java.io.PrintStream;
|
||||
|
||||
@PermissionStub(permission = Permission.File)
|
||||
public class FileUtil extends org.bdware.sc.util.FileUtil {
|
||||
private static String getInternalFile(String path) {
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
if (path.contains("..")) {
|
||||
return null;
|
||||
}
|
||||
File f = new File(parent, path);
|
||||
return f.getAbsolutePath();
|
||||
}
|
||||
|
||||
public static String getContent(String path) {
|
||||
return getFileContent(getInternalFile(path));
|
||||
}
|
||||
|
||||
public static void copyTo(String src, String dst) {
|
||||
try {
|
||||
String from = getInternalFile(src);
|
||||
String to = getInternalFile(dst);
|
||||
if (null == from || null == to) {
|
||||
throw new ScriptException("incorrect file name of from /to");
|
||||
}
|
||||
copyFile(from, to);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static PrintStream openAsPrinter(String path, boolean isAppend) {
|
||||
return openFileAsPrinter(getInternalFile(path), isAppend);
|
||||
}
|
||||
}
|
||||
11
src/main/java/org/bdware/sc/boundry/utils/FileUtilStub.java
Normal file
11
src/main/java/org/bdware/sc/boundry/utils/FileUtilStub.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import javax.script.ScriptException;
|
||||
|
||||
public class FileUtilStub {
|
||||
|
||||
public static String getDir(String fullFileName) throws ScriptException {
|
||||
throw new ScriptException("Do not have File Permission");
|
||||
}
|
||||
|
||||
}
|
||||
307
src/main/java/org/bdware/sc/boundry/utils/HttpUtil.java
Normal file
307
src/main/java/org/bdware/sc/boundry/utils/HttpUtil.java
Normal file
@@ -0,0 +1,307 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import okhttp3.*;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.http.ApiGate;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import java.io.*;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Scanner;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@PermissionStub(permission = Permission.Http)
|
||||
public class HttpUtil {
|
||||
public static NashornScriptEngine currentEngine;
|
||||
|
||||
public static ScriptObject request(ScriptObjectMirror str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL((String) str.get("url"));
|
||||
String method = (String) str.get("method");
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
connection.setRequestMethod(method.toUpperCase());
|
||||
Object headers = str.get("headers");
|
||||
if (headers != null && headers instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) headers;
|
||||
for (String key : som.getOwnKeys(true)) {
|
||||
Object val = som.get(key);
|
||||
if (val instanceof String) connection.setRequestProperty(key, (String) val);
|
||||
}
|
||||
} else {
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
}
|
||||
connection.connect();
|
||||
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8");
|
||||
if (str.get("data") != null)
|
||||
out.append((String) str.get("data"));
|
||||
out.flush();
|
||||
out.close();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (; sc.hasNextLine(); ) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("responseCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
public static String encodeURI(String str){
|
||||
return URLEncoder.encode(str);
|
||||
}
|
||||
public static String decodeURI(String str){
|
||||
return URLDecoder.decode(str);
|
||||
}
|
||||
|
||||
public static ScriptObject get(String str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL(str);
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (sc.hasNextLine()) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("resposeCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject post(ScriptObjectMirror str) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
URL url = new URL((String) str.get("url"));
|
||||
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
connection.setDoOutput(true);
|
||||
connection.setDoInput(true);
|
||||
connection.setUseCaches(false);
|
||||
connection.setInstanceFollowRedirects(true);
|
||||
connection.setRequestMethod("POST");
|
||||
Object headers = str.get("headers");
|
||||
if (headers instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) headers;
|
||||
for (String key : som.getOwnKeys(true)) {
|
||||
Object val = som.get(key);
|
||||
if (val instanceof String) {
|
||||
connection.setRequestProperty(key, (String) val);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
connection.setRequestProperty("Accept", "application/json");
|
||||
connection.setRequestProperty("Content-Type", "application/json");
|
||||
}
|
||||
connection.connect();
|
||||
OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), StandardCharsets.UTF_8);
|
||||
out.append((String) str.get("data"));
|
||||
out.flush();
|
||||
out.close();
|
||||
ret.put("responseCode", connection.getResponseCode(), false);
|
||||
InputStream input = connection.getInputStream();
|
||||
Scanner sc = new Scanner(input);
|
||||
StringBuilder sb = new StringBuilder();
|
||||
while (sc.hasNextLine()) {
|
||||
sb.append(sc.nextLine()).append("\n");
|
||||
}
|
||||
sc.close();
|
||||
ret.put("response", sb.toString(), false);
|
||||
} catch (Throwable e) {
|
||||
ret.put("responseCode", 505, false);
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
ret.put("response", bo.toString(), false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static CloseableHttpClient getHttpClient(String url) {
|
||||
try {
|
||||
SSLContext sslcontext =
|
||||
SSLContexts.custom()
|
||||
.loadTrustMaterial(
|
||||
null,
|
||||
(arg0, arg1) -> true)
|
||||
.build();
|
||||
|
||||
SSLConnectionSocketFactory sslSf =
|
||||
new SSLConnectionSocketFactory(
|
||||
sslcontext, null, null, new NoopHostnameVerifier());
|
||||
int tle = 10;
|
||||
if (url.contains("data.tj.gov.cn")) {
|
||||
tle = 3;
|
||||
}
|
||||
return HttpClients.custom()
|
||||
.setSSLSocketFactory(sslSf)
|
||||
.setKeepAliveStrategy((arg0, arg1) -> 0)
|
||||
.setConnectionTimeToLive(tle, TimeUnit.SECONDS)
|
||||
.build();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// public static String httpPost(String str) {
|
||||
// System.out.println("JavaSScriptEntry httpPost:" + str);
|
||||
// PostRequest req = new PostRequest();
|
||||
// req = JsonUtil.fromJson(str, PostRequest.class);
|
||||
// // System.out.println("url========>" + req.url);
|
||||
// // System.out.println("data=======>" + req.data);
|
||||
//
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// URL url = new URL(req.url);//
|
||||
// HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
||||
// connection.setDoOutput(true);
|
||||
// connection.setDoInput(true);
|
||||
// connection.setUseCaches(false);
|
||||
// connection.setInstanceFollowRedirects(true);
|
||||
// connection.setRequestMethod("POST");
|
||||
// connection.setRequestProperty("Accept", "application/json");
|
||||
// connection.setRequestProperty("Content-Type", "application/json");
|
||||
// connection.connect();
|
||||
// OutputStreamWriter out = new OutputStreamWriter(connection.getOutputStream(), "UTF-8"); //
|
||||
// utf-8缂栫爜
|
||||
// out.append(req.data);
|
||||
// out.flush();
|
||||
// out.close();
|
||||
//
|
||||
// r.resposeCode = connection.getResponseCode();
|
||||
// InputStream input = connection.getInputStream();
|
||||
//
|
||||
// Scanner sc = new Scanner(input);
|
||||
// StringBuilder sb = new StringBuilder();
|
||||
// for (; sc.hasNextLine();) {
|
||||
// sb.append(sc.nextLine()).append("\n");
|
||||
// }
|
||||
// sc.close();
|
||||
// r.response = sb.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static String postTask(String args, final ScriptFunction callback) {
|
||||
System.out.println("[JavaScriptEntry]" + args);
|
||||
PostRequest req = new PostRequest();
|
||||
req = JsonUtil.fromJson(args, PostRequest.class);
|
||||
|
||||
OkHttpClient okHttpClient = new OkHttpClient(); //
|
||||
RequestBody body =
|
||||
RequestBody.create(MediaType.parse("application/json; charset=utf-8"), req.data);
|
||||
Request request = new Request.Builder().url(req.url).post(body).build(); // 2.瀹氫箟涓<E7AE9F>涓猺equest
|
||||
Call call = okHttpClient.newCall(request); //
|
||||
call.enqueue(
|
||||
new Callback() { //
|
||||
@Override
|
||||
public void onFailure(Call call, IOException e) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(Call call, Response response) throws IOException {
|
||||
String result = response.body().string(); //
|
||||
System.out.println("currentEngine:");
|
||||
DesktopEngine.applyWithGlobal(
|
||||
callback, currentEngine.getNashornGlobal(), result);
|
||||
}
|
||||
});
|
||||
return "success";
|
||||
}
|
||||
|
||||
// public static String httpGet(String str) {
|
||||
// // System.out.println("JavaScriptEntry httpGet:" + str);
|
||||
// Result r = new Result();
|
||||
// try {
|
||||
// HttpGet httpGet = new HttpGet(str);
|
||||
// RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(60000)
|
||||
// .setConnectTimeout(60000).setSocketTimeout(60000).build();
|
||||
// httpGet.setConfig(requestConfig);
|
||||
// httpGet.addHeader("Pragma", "no-cache");
|
||||
// httpGet.addHeader("Cache-Control", "no-cache");
|
||||
// httpGet.addHeader("Upgrade-Insecure-Requests", "1");
|
||||
// httpGet.addHeader("User-Agent",
|
||||
// "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko)
|
||||
// Chrome/78.0.3904.97 Safari/537.36");
|
||||
// httpGet.addHeader("Sec-Fetch-User", "?1");
|
||||
// httpGet.addHeader("Accept",
|
||||
//
|
||||
// "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3");
|
||||
// httpGet.addHeader("Sec-Fetch-Site", "none");
|
||||
// httpGet.addHeader("Sec-Fetch-Mode", "navigate");
|
||||
// httpGet.addHeader("Accept-Encoding", "gzip, deflate, br");
|
||||
// httpGet.addHeader("Accept-Language", "zh-CN,zh;q=0.9");
|
||||
// CloseableHttpResponse response1 = getHttpClient(str).execute(httpGet);
|
||||
// InputStream content = response1.getEntity().getContent();
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// byte[] buff = new byte[4096];
|
||||
// for (int k = 0; (k = content.read(buff)) > 0;) {
|
||||
// bo.write(buff, 0, k);
|
||||
// }
|
||||
// r.response = bo.toString();
|
||||
// return JsonUtil.toJson(r);
|
||||
// } catch (Throwable e) {
|
||||
// r.resposeCode = 505;
|
||||
// // ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// // e.printStackTrace(new PrintStream(bo));
|
||||
// r.response = e.getMessage();
|
||||
// return JsonUtil.toJson(r);
|
||||
// }
|
||||
// }
|
||||
|
||||
public static ApiGate createAPIGate(String ip) {
|
||||
return new ApiGate(ip);
|
||||
}
|
||||
|
||||
public static ApiGate createAPIGate(String ip, String port) {
|
||||
return new ApiGate(ip, Integer.parseInt(port));
|
||||
}
|
||||
|
||||
static class PostRequest {
|
||||
String url;
|
||||
String data;
|
||||
}
|
||||
}
|
||||
54
src/main/java/org/bdware/sc/boundry/utils/LedgerUtil.java
Normal file
54
src/main/java/org/bdware/sc/boundry/utils/LedgerUtil.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.bdledger.api.grpc.Client;
|
||||
import org.bdware.bdledger.api.grpc.pb.CommonProto.Transaction;
|
||||
import org.bdware.bdledger.api.grpc.pb.CommonProto.TransactionType;
|
||||
import org.bdware.bdledger.api.grpc.pb.LedgerProto.SendTransactionResponse;
|
||||
import org.bdware.bdledger.api.grpc.pb.QueryProto.GetTransactionByHashResponse;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bdware.sc.util.HashUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
|
||||
@PermissionStub(permission = Permission.Ledger)
|
||||
public class LedgerUtil {
|
||||
static SecureRandom random = new SecureRandom((System.currentTimeMillis() + "").getBytes());
|
||||
|
||||
public static Client getClient(ScriptObjectMirror str) {
|
||||
return new Client((String) str.get("ip"), Integer.parseInt(str.get("port").toString()));
|
||||
}
|
||||
|
||||
public static ScriptObject queryByHash(Client c, ScriptObjectMirror str) {
|
||||
String ledger = str.get("ledger").toString();
|
||||
String hash = str.get("hash").toString();
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
GetTransactionByHashResponse result = c.getTransactionByHashSync(ledger, hash);
|
||||
Transaction transaction = result.getTransaction();
|
||||
ret.put("from", HashUtil.byteArray2Str(transaction.getFrom().toByteArray(), 0), false);
|
||||
ret.put("to", HashUtil.byteArray2Str(transaction.getTo().toByteArray(), 0), false);
|
||||
ret.put("type", transaction.getType().toString(), false);
|
||||
ret.put("data", new String(transaction.getData().toByteArray()), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String sendTransaction(Client c, ScriptObjectMirror str) {
|
||||
String ledger = str.get("ledger").toString();
|
||||
String from = str.get("from").toString();
|
||||
String to = str.get("to").toString();
|
||||
String data = str.get("data").toString();
|
||||
SendTransactionResponse result =
|
||||
c.sendTransactionSync(
|
||||
ledger,
|
||||
TransactionType.MESSAGE,
|
||||
from,
|
||||
random.nextLong(),
|
||||
to,
|
||||
data.getBytes());
|
||||
return HashUtil.byteArray2Str(result.getHash().toByteArray(), 0);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
@PermissionStub(permission = Permission.MongoDB)
|
||||
public class MongoDBUtil extends org.bdware.sc.blockdb.MongoDBUtil {
|
||||
}
|
||||
19
src/main/java/org/bdware/sc/boundry/utils/README.md
Normal file
19
src/main/java/org/bdware/sc/boundry/utils/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# 简介
|
||||
|
||||
这个包里对yjs层提供了XXUtil功能的调用。 要添加一个Util需要以下步骤。
|
||||
|
||||
## 1.新增加一个带@PermissionStub的注解
|
||||
|
||||
注意注解里的Permission要和类名一致。
|
||||
|
||||
```java
|
||||
|
||||
@PermissionStub(permission = "ABC")
|
||||
public class ABCUtil {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
## 2.在org.bdware.sc.node.Permission中添加这个权限
|
||||
|
||||
## 3.在doc项目的@Permission注解说明里
|
||||
105
src/main/java/org/bdware/sc/boundry/utils/RocksDBUtil.java
Normal file
105
src/main/java/org/bdware/sc/boundry/utils/RocksDBUtil.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.rocksdb.Options;
|
||||
import org.rocksdb.RocksDB;
|
||||
import org.rocksdb.RocksDBException;
|
||||
import org.rocksdb.RocksIterator;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@PermissionStub(permission = Permission.RocksDB)
|
||||
public class RocksDBUtil {
|
||||
static {
|
||||
RocksDB.loadLibrary();
|
||||
}
|
||||
|
||||
RocksDB rocksDB;
|
||||
|
||||
public RocksDBUtil(String path, boolean readOnly) {
|
||||
try {
|
||||
Options options = new Options();
|
||||
options.setCreateIfMissing(true);
|
||||
File parent = new File("./ContractDB/" + ContractProcess.instance.getContractName());
|
||||
path = new File(parent, path).getAbsolutePath();
|
||||
File lockFile = new File(path, "LOCK");
|
||||
lockFile.delete();
|
||||
if (readOnly) {
|
||||
rocksDB = RocksDB.openReadOnly(options, path);
|
||||
} else rocksDB = RocksDB.open(options, path);
|
||||
} catch (RocksDBException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static RocksDBUtil loadDB(String path, boolean readOnly) {
|
||||
return new RocksDBUtil(path, readOnly);
|
||||
}
|
||||
|
||||
public static RocksDBUtil loadDB(String path, String readOnly) {
|
||||
return new RocksDBUtil(path, Boolean.parseBoolean(readOnly));
|
||||
}
|
||||
|
||||
public String get(String key) {
|
||||
try {
|
||||
return new String(rocksDB.get(key.getBytes()));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public long estimateKeySize() {
|
||||
try {
|
||||
return rocksDB.getLongProperty("rocksdb.estimate-num-keys");
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String key, String value) {
|
||||
try {
|
||||
rocksDB.put(key.getBytes(), value.getBytes());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String delete(String key) {
|
||||
try {
|
||||
rocksDB.delete(key.getBytes());
|
||||
|
||||
return "success";
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "failed";
|
||||
}
|
||||
|
||||
public RocksIterator newIterator() {
|
||||
try {
|
||||
return rocksDB.newIterator();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public ScriptObject getNext(RocksIterator iter) {
|
||||
|
||||
if (iter.isValid()) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
ret.put("key", new String(iter.key()), false);
|
||||
ret.put("value", new String(iter.value()), false);
|
||||
iter.next();
|
||||
return ret;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
93
src/main/java/org/bdware/sc/boundry/utils/SM2Util.java
Normal file
93
src/main/java/org/bdware/sc/boundry/utils/SM2Util.java
Normal file
@@ -0,0 +1,93 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
import org.bouncycastle.crypto.InvalidCipherTextException;
|
||||
import org.bouncycastle.crypto.params.ECPrivateKeyParameters;
|
||||
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
|
||||
import org.bouncycastle.pqc.math.linearalgebra.ByteUtils;
|
||||
import org.zz.gmhelper.BCECUtil;
|
||||
import org.zz.gmhelper.SM2KeyPair;
|
||||
import org.zz.gmhelper.SM3Util;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
@PermissionStub(permission = Permission.SM2)
|
||||
public class SM2Util {
|
||||
|
||||
public static ScriptObject generateKeyPair() {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
SM2KeyPair keyPair = org.zz.gmhelper.SM2Util.generateSM2KeyPair();
|
||||
ret.put("publicKey", keyPair.getPublicKeyStr(), false);
|
||||
ret.put("privateKey", keyPair.getPrivateKeyStr(), false);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject sign(String content, ScriptObjectMirror keyPair) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
BigInteger privateKey = new BigInteger(keyPair.getMember("privateKey").toString(), 16);
|
||||
ECPrivateKeyParameters priKey =
|
||||
new ECPrivateKeyParameters(privateKey, org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
byte[] sign = org.zz.gmhelper.SM2Util.sign(priKey, content.getBytes());
|
||||
sign = org.zz.gmhelper.SM2Util.decodeDERSM2Sign(sign);
|
||||
ret.put("status", "success", false);
|
||||
ret.put("signature", ByteUtils.toHexString(sign), false);
|
||||
} catch (Exception e) {
|
||||
ret.put("status", "failed", false);
|
||||
ret.put("message", "invalid keyPair", false);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static ScriptObject verify(String content, String signature, String pubKeyStr) {
|
||||
JO ret = new JO(PropertyMap.newMap());
|
||||
try {
|
||||
byte[] sig = ByteUtils.fromHexString(signature);
|
||||
sig = org.zz.gmhelper.SM2Util.encodeSM2SignToDER(sig);
|
||||
ECPublicKeyParameters pubKey =
|
||||
BCECUtil.createECPublicKeyFromStrParameters(
|
||||
pubKeyStr,
|
||||
org.zz.gmhelper.SM2Util.CURVE,
|
||||
org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
boolean value = org.zz.gmhelper.SM2Util.verify(pubKey, content.getBytes(), sig);
|
||||
if (value) ret.put("status", "success", false);
|
||||
else ret.put("status", "failed", false);
|
||||
ret.put("result", value, false);
|
||||
} catch (Exception e) {
|
||||
ret.put("status", "failed", false);
|
||||
ret.put("result", "invalid keyPair or signature ", false);
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static String encrypt(String content, String pubkey) {
|
||||
try {
|
||||
return ByteUtils.toHexString(
|
||||
org.zz.gmhelper.SM2Util.encrypt(
|
||||
SM2KeyPair.publicKeyStr2ECPoint(pubkey), content.getBytes()));
|
||||
} catch (InvalidCipherTextException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static String decrypt(String content, String privateKey) {
|
||||
try {
|
||||
ECPrivateKeyParameters privateKeyParam =
|
||||
new ECPrivateKeyParameters(
|
||||
new BigInteger(privateKey, 16), org.zz.gmhelper.SM2Util.DOMAIN_PARAMS);
|
||||
return new String(
|
||||
org.zz.gmhelper.SM2Util.decrypt(
|
||||
privateKeyParam, ByteUtils.fromHexString(content)));
|
||||
} catch (InvalidCipherTextException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
62
src/main/java/org/bdware/sc/boundry/utils/SQLUtil.java
Normal file
62
src/main/java/org/bdware/sc/boundry/utils/SQLUtil.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.Connection;
|
||||
import java.util.Properties;
|
||||
|
||||
@PermissionStub(permission = Permission.SQL)
|
||||
public class SQLUtil {
|
||||
public static void initDriver(String driver) {
|
||||
try {
|
||||
Thread.currentThread()
|
||||
.setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
|
||||
Class.forName(driver, true, ContractProcess.instance.engine.getClassLoad());
|
||||
} catch (Exception e) {
|
||||
System.out.println(
|
||||
"Still can't find class! Cl of SQLUtil:\n\t\t"
|
||||
+ SQLUtil.class.getClassLoader());
|
||||
System.out.println(
|
||||
"Cl of DEgine:\n\t\t" + ContractProcess.instance.engine.getClassLoad());
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static Connection getConnection(String url, String user, String password) {
|
||||
try {
|
||||
Thread.currentThread()
|
||||
.setContextClassLoader(ContractProcess.instance.engine.getClassLoad());
|
||||
if (!url.startsWith("jdbc")) {
|
||||
url += "jdbc:mysql://";
|
||||
}
|
||||
java.util.Properties info = new java.util.Properties();
|
||||
|
||||
if (user != null && !"undefined".equals(user)) {
|
||||
info.put("user", user);
|
||||
}
|
||||
if (password != null && !"undefined".equals(password)) {
|
||||
info.put("password", password);
|
||||
}
|
||||
if (url.startsWith("jdbc:postgresql")) info.put("sslmode", "allow");
|
||||
|
||||
Class<?> clz =
|
||||
Class.forName(
|
||||
"java.sql.DriverManager",
|
||||
true,
|
||||
ContractProcess.instance.engine.getClassLoad());
|
||||
// set caller class into null, thus use YJSClassLoader in
|
||||
// DriverManager.isDriverAllowed(driver,classloader);
|
||||
Method m =
|
||||
clz.getDeclaredMethod(
|
||||
"getConnection", String.class, Properties.class, Class.class);
|
||||
m.setAccessible(true);
|
||||
return (Connection) m.invoke(null, url, info, null);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
59
src/main/java/org/bdware/sc/boundry/utils/UtilRegistry.java
Normal file
59
src/main/java/org/bdware/sc/boundry/utils/UtilRegistry.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package org.bdware.sc.boundry.utils;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.compiler.PermissionStub;
|
||||
import org.bdware.sc.compiler.PermissionStubGenerator;
|
||||
import org.bdware.sc.engine.YJSClassLoader;
|
||||
import org.bdware.sc.node.Permission;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class UtilRegistry {
|
||||
private static final Logger LOGGER = LogManager.getLogger(UtilRegistry.class);
|
||||
public static Map<String, String> stubClzNameMap = new HashMap<>();
|
||||
|
||||
public static List<Class<?>> getUtilClasses() {
|
||||
List<String> allName = Permission.allName();
|
||||
List<Class<?>> ret = new ArrayList<>();
|
||||
for (String name : allName) {
|
||||
Class<?> clz;
|
||||
try {
|
||||
clz = Class.forName(String.format("%s.%sUtil", UtilRegistry.class.getPackage().getName(), name));
|
||||
ret.add(clz);
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
public static void defineUtilClass(YJSClassLoader classLoader) {
|
||||
List<Class<?>> clzs = UtilRegistry.getUtilClasses();
|
||||
for (Class<?> aClass : clzs) {
|
||||
PermissionStub stub = aClass.getAnnotation(PermissionStub.class);
|
||||
if (stub == null) {
|
||||
continue;
|
||||
}
|
||||
byte[] stubClz = PermissionStubGenerator.generateStub(aClass, stub.permission().name());
|
||||
String stubClzName = aClass.getCanonicalName() + "Stub";
|
||||
stubClzNameMap.put(stub.permission().name(), stubClzName);
|
||||
classLoader.defineStubClass(stubClzName, stubClz);
|
||||
}
|
||||
}
|
||||
|
||||
public static String getInitStr(String s, boolean open) {
|
||||
if (stubClzNameMap.containsKey(s)) {
|
||||
String ret =
|
||||
String.format(
|
||||
"%sUtil = %s.%sUtil%s;\n",
|
||||
s, UtilRegistry.class.getPackage().getName(), s, open ? "" : "Stub");
|
||||
LOGGER.debug(ret);
|
||||
return ret;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package org.bdware.sc.compiler;
|
||||
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public abstract class AnnotationProcessor {
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
224
src/main/java/org/bdware/sc/compiler/YJSCompiler.java
Normal file
224
src/main/java/org/bdware/sc/compiler/YJSCompiler.java
Normal file
@@ -0,0 +1,224 @@
|
||||
package org.bdware.sc.compiler;
|
||||
|
||||
import org.antlr.v4.runtime.ANTLRInputStream;
|
||||
import org.antlr.v4.runtime.CommonTokenStream;
|
||||
import org.antlr.v4.runtime.DiagnosticErrorListener;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.engine.YJSFilter;
|
||||
import org.bdware.sc.node.*;
|
||||
import org.bdware.sc.parser.JavaScriptLexer;
|
||||
import org.bdware.sc.parser.YJSParser;
|
||||
import org.bdware.sc.parser.YJSParser.ProgramContext;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.bdware.sc.visitor.ContractReader;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.ErrorManager;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.Source;
|
||||
import wrp.jdk.nashorn.internal.runtime.options.Options;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class YJSCompiler {
|
||||
public boolean withProgramPointCount;
|
||||
YJSErrorListener errorListener = new YJSErrorListener();
|
||||
ContractNode contract;
|
||||
private static final Logger LOGGER = LogManager.getLogger(YJSCompiler.class);
|
||||
|
||||
public YJSCompiler() {
|
||||
}
|
||||
|
||||
public static ScriptFunction compileWithGlobal(Source source, Global global, Context context) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
return context.compileScript(source).getFunction(global);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Context makeContext(
|
||||
final InputStream in, final OutputStream out, final OutputStream err) {
|
||||
final PrintStream pout =
|
||||
out instanceof PrintStream ? (PrintStream) out : new PrintStream(out);
|
||||
final PrintStream perr =
|
||||
err instanceof PrintStream ? (PrintStream) err : new PrintStream(err);
|
||||
final PrintWriter wout = new PrintWriter(pout, true);
|
||||
final PrintWriter werr = new PrintWriter(perr, true);
|
||||
|
||||
// Set up error handler.
|
||||
final ErrorManager errors = new ErrorManager(werr);
|
||||
// Set up options.
|
||||
final Options options = new Options("nashorn", werr);
|
||||
options.process(new String[] {});
|
||||
// detect scripting mode by any source's first character being '#'
|
||||
options.set("persistent.code.cache", true);
|
||||
options.set("print.code", "true");
|
||||
options.set("print.parse", true);
|
||||
|
||||
if (!options.getBoolean("scripting")) {
|
||||
for (final String fileName : options.getFiles()) {
|
||||
final File firstFile = new File(fileName);
|
||||
if (firstFile.isFile()) {
|
||||
try (final FileReader fr = new FileReader(firstFile)) {
|
||||
final int firstChar = fr.read();
|
||||
// starts with '#
|
||||
if (firstChar == '#') {
|
||||
options.set("scripting", true);
|
||||
break;
|
||||
}
|
||||
} catch (final IOException e) {
|
||||
// ignore this. File IO errors will be reported later
|
||||
// anyway
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return new Context(
|
||||
options,
|
||||
errors,
|
||||
wout,
|
||||
werr,
|
||||
Thread.currentThread().getContextClassLoader(),
|
||||
new YJSFilter(),
|
||||
null);
|
||||
}
|
||||
|
||||
public ContractZipBundle compile(ZipFile zf) throws Exception {
|
||||
ContractZipBundle czb = new ContractZipBundle();
|
||||
ZipEntry manifest = zf.getEntry("/manifest.json");
|
||||
if (null == manifest) {
|
||||
throw new IllegalStateException("manifest.json is not exists!");
|
||||
}
|
||||
InputStream manifestInput = zf.getInputStream(manifest);
|
||||
// Gson gson = new GsonBuilder().registerTypeAdapter(Contract.Type.class,
|
||||
// typeAdapter)
|
||||
|
||||
ContractManifest cm =
|
||||
JsonUtil.GSON.fromJson(
|
||||
new InputStreamReader(manifestInput), ContractManifest.class);
|
||||
|
||||
// 如果没有就不限制,根据gas进行插装
|
||||
if (0L != cm.getInsnLimit()) {
|
||||
System.out.println("++++++++++++++++++++++true");
|
||||
}
|
||||
czb.setManifest(cm);
|
||||
Set<String> toParse = new HashSet<>();
|
||||
toParse.add(cm.main);
|
||||
Set<String> todo = new HashSet<>();
|
||||
while (toParse.size() > 0) {
|
||||
for (String str : toParse) {
|
||||
if (czb.containsPath(str)) {
|
||||
continue;
|
||||
}
|
||||
ZipEntry entry = zf.getEntry("/" + str);
|
||||
if (null == entry) {
|
||||
throw new IllegalStateException("missing import:" + str);
|
||||
}
|
||||
ContractNode cn = compile(zf.getInputStream(entry), str);
|
||||
czb.put(str, cn);
|
||||
System.out.println("----" + str);
|
||||
for (ImportNode in : cn.getImports()) {
|
||||
todo.add(in.getPath());
|
||||
}
|
||||
}
|
||||
toParse.clear();
|
||||
for (String str : todo) {
|
||||
if (!czb.containsPath(str)) {
|
||||
toParse.add(str);
|
||||
}
|
||||
}
|
||||
todo.clear();
|
||||
}
|
||||
// add function _preSub
|
||||
// Kaidong Wu
|
||||
String preSubConName = cm.main.substring(0, cm.main.length() - 4) + "PreSub";
|
||||
String preSubContract =
|
||||
"contract "
|
||||
+ preSubConName
|
||||
+ " { function _preSub (e) { YancloudUtil.preSub(e.topic, e.content); }}";
|
||||
ContractNode preSubNode =
|
||||
compile(
|
||||
new ByteArrayInputStream(preSubContract.getBytes(StandardCharsets.UTF_8)),
|
||||
preSubConName + ".yjs");
|
||||
czb.put(preSubConName + ".yjs", preSubNode);
|
||||
LOGGER.info("--compile-- " + preSubConName);
|
||||
return czb;
|
||||
}
|
||||
|
||||
public ContractNode compile(InputStream input, String fileName) throws IOException {
|
||||
// 词法分析
|
||||
JavaScriptLexer lexer = new JavaScriptLexer(new ANTLRInputStream(input));
|
||||
lexer.setUseStrictDefault(true);
|
||||
CommonTokenStream cts = new CommonTokenStream(lexer);
|
||||
// 语法分析
|
||||
YJSParser parser = new YJSParser(cts);
|
||||
parser.removeErrorListeners();
|
||||
parser.addErrorListener(errorListener);
|
||||
parser.addErrorListener(new DiagnosticErrorListener());
|
||||
ProgramContext tree = parser.program();
|
||||
// 应该是antlr4访问器进行遍历语法树
|
||||
ContractReader reader = new ContractReader(fileName);
|
||||
System.out.println("遍历语法树");
|
||||
contract = reader.visitProgram(tree);
|
||||
// 遍历完 获取 contract 里的 yjs type
|
||||
System.out.println(contract.getYjsType());
|
||||
contract.initPlainText(cts);
|
||||
handleAnnotation(contract);//处理注解
|
||||
return contract;
|
||||
}
|
||||
|
||||
private void handleAnnotation(ContractNode contractNode) {
|
||||
System.out.println("handleAnnotation");
|
||||
for (AnnotationNode node : contract.annotations) {
|
||||
AnnotationProcessor processor = findProcessor(node);
|
||||
if (processor != null) {
|
||||
processor.processContract(node, contractNode);
|
||||
}
|
||||
}
|
||||
for (FunctionNode functionNode : contractNode.getFunctions()) {
|
||||
List<AnnotationNode> annos = functionNode.annotations;//函数里的annotation
|
||||
if (annos != null)
|
||||
for (AnnotationNode anno : annos) {
|
||||
System.out.println(anno.getType());//打印类型和参数
|
||||
System.out.println(anno.getArgs());
|
||||
AnnotationProcessor processor = findProcessor(anno);
|
||||
if (processor != null)
|
||||
processor.processFunction(anno, contractNode, functionNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationProcessor findProcessor(AnnotationNode node) {
|
||||
try {
|
||||
String clzName = YJSCompiler.class.getPackage().getName();
|
||||
clzName += ".ap." + node.getType();
|
||||
Class<?> clz = Class.forName(clzName);
|
||||
return (AnnotationProcessor) clz.getConstructor().newInstance();
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> syntaxError() {
|
||||
return errorListener.result;
|
||||
}
|
||||
}
|
||||
15
src/main/java/org/bdware/sc/compiler/ap/Access.java
Normal file
15
src/main/java/org/bdware/sc/compiler/ap/Access.java
Normal file
@@ -0,0 +1,15 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
|
||||
public class Access extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.sigRequired = false;
|
||||
if (anno != null) {
|
||||
contractNode.sigRequired = "\"verified\"".equals(anno.getArgs().get(0));
|
||||
}
|
||||
}
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/compiler/ap/Confidential.java
Normal file
12
src/main/java/org/bdware/sc/compiler/ap/Confidential.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Confidential extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setConfidential(true); }
|
||||
}
|
||||
19
src/main/java/org/bdware/sc/compiler/ap/Cost.java
Normal file
19
src/main/java/org/bdware/sc/compiler/ap/Cost.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.CostDetail;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
public class Cost extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
CostDetail detail = JsonUtil.fromJson(anno.getArgs().get(0), CostDetail.class);
|
||||
functionNode.setCost(detail);
|
||||
if (detail.isCountGas())
|
||||
contractNode.setInstrumentBranch(true);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class HomomorphicDecrypt extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setHomomorphicDecrypt(true);
|
||||
functionNode.setKeyManagerID(anno.getArgs().get(0));
|
||||
functionNode.setSecretID(anno.getArgs().get(1));
|
||||
functionNode.setHomoDecryptConf(JsonParser.parseString(anno.getArgs().get(2)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.JsonParser;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class HomomorphicEncrypt extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setHomomorphicEncrypt(true);
|
||||
functionNode.setKeyManagerID(anno.getArgs().get(0));
|
||||
functionNode.setSecretID(anno.getArgs().get(1));
|
||||
functionNode.setHomoEncryptConf(JsonParser.parseString(anno.getArgs().get(2)));
|
||||
}
|
||||
}
|
||||
17
src/main/java/org/bdware/sc/compiler/ap/Join.java
Normal file
17
src/main/java/org/bdware/sc/compiler/ap/Join.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.bean.JoinInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Join extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
// functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
//增加标记,在ContractNode中记录Join相关的函数和Join规则
|
||||
functionNode.setJoinInfo(JoinInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
||||
32
src/main/java/org/bdware/sc/compiler/ap/LogLocation.java
Normal file
32
src/main/java/org/bdware/sc/compiler/ap/LogLocation.java
Normal file
@@ -0,0 +1,32 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class LogLocation extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
for (FunctionNode fn : contractNode.getFunctions()) {
|
||||
fn.addAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
if (anno != null && anno.getArgs() != null)
|
||||
for (String s : anno.getArgs()) {
|
||||
if (s.equals("\"dataware\"")
|
||||
|| s.equals("\"bdledger\"")
|
||||
|| s.equals("\"bdledger:\"")) {
|
||||
functionNode.setLogToBDContract(true);
|
||||
} else if (s.startsWith("\"bdledger:") && s.length() > 11) {
|
||||
functionNode.setLogToNamedLedger(true);
|
||||
String[] tmp = s.substring(1, s.length() - 1).split(":");
|
||||
functionNode.addLedgerName(tmp[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
26
src/main/java/org/bdware/sc/compiler/ap/LogType.java
Normal file
26
src/main/java/org/bdware/sc/compiler/ap/LogType.java
Normal file
@@ -0,0 +1,26 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class LogType extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.setLogType(anno.getArgs());
|
||||
for (FunctionNode fn : contractNode.getFunctions()) {
|
||||
fn.addAnnotation(anno);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
for (String str : anno.getArgs()) {
|
||||
org.bdware.sc.node.LogType type = org.bdware.sc.node.LogType.parse(str);
|
||||
functionNode.addLogType(type);
|
||||
if (type == org.bdware.sc.node.LogType.Branch) contractNode.setInstrumentBranch(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
6
src/main/java/org/bdware/sc/compiler/ap/Param.java
Normal file
6
src/main/java/org/bdware/sc/compiler/ap/Param.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
|
||||
public class Param extends AnnotationProcessor {
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/compiler/ap/Permission.java
Normal file
12
src/main/java/org/bdware/sc/compiler/ap/Permission.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
|
||||
public class Permission extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processContract(AnnotationNode anno, ContractNode contractNode) {
|
||||
contractNode.setPermission(anno.getArgs());
|
||||
}
|
||||
}
|
||||
17
src/main/java/org/bdware/sc/compiler/ap/Route.java
Normal file
17
src/main/java/org/bdware/sc/compiler/ap/Route.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import org.bdware.sc.bean.RouteInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.CostDetail;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Route extends AnnotationProcessor {
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
||||
16
src/main/java/org/bdware/sc/compiler/ap/Split.java
Normal file
16
src/main/java/org/bdware/sc/compiler/ap/Split.java
Normal file
@@ -0,0 +1,16 @@
|
||||
package org.bdware.sc.compiler.ap;
|
||||
|
||||
import org.bdware.sc.bean.RouteInfo;
|
||||
import org.bdware.sc.compiler.AnnotationProcessor;
|
||||
import org.bdware.sc.node.AnnotationNode;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
|
||||
public class Split extends AnnotationProcessor {
|
||||
|
||||
@Override
|
||||
public void processFunction(
|
||||
AnnotationNode anno, ContractNode contractNode, FunctionNode functionNode) {
|
||||
functionNode.setRouteInfo(RouteInfo.create(anno,contractNode));
|
||||
}
|
||||
}
|
||||
323
src/main/java/org/bdware/sc/engine/ConfidentialContractUtil.java
Normal file
323
src/main/java/org/bdware/sc/engine/ConfidentialContractUtil.java
Normal file
@@ -0,0 +1,323 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.node.ContractNode;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptException;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.*;
|
||||
|
||||
public class ConfidentialContractUtil {
|
||||
|
||||
public static final String CONFIDENTIAL_TEMPLATE_PATH = System.getenv("GRAPHENE_DIR")
|
||||
+ File.separator + "Examples" + File.separator + "nodejs-secret";
|
||||
public static final String CONFIDENTIAL_SCRIPT_PATH = System.getenv("GRAPHENE_DIR")
|
||||
+ File.separator + "App";
|
||||
public static final String[] COMMAND = {"bash", "executeContract.sh"};
|
||||
private static final Type MapType = TypeToken.getParameterized(HashMap.class, String.class, String.class).getType();
|
||||
|
||||
public static String executeConfidentialContract(ContractRequest input) throws IOException, InterruptedException {
|
||||
File runDir = new File(CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID());
|
||||
ProcessBuilder pb = new ProcessBuilder(COMMAND);
|
||||
pb.directory(runDir);
|
||||
Process p = pb.start();
|
||||
p.waitFor();
|
||||
File resultFile = new File(CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID() +
|
||||
File.separator + "result.json");
|
||||
return FileUtils.readFileToString(resultFile, StandardCharsets.UTF_8);
|
||||
}
|
||||
|
||||
public static void generateConfidentialContract(ContractNode cn, ScriptObjectMirror globalVars, Global global) {
|
||||
List<FunctionNode> functionNodes = cn.getFunctions();
|
||||
for (FunctionNode fn : functionNodes) {
|
||||
// assuming only one confidential function for now
|
||||
if (fn.isConfidential()) {
|
||||
StringBuilder jsStr = new StringBuilder();
|
||||
// find all dependent functions
|
||||
Set<String> dependentFunctions = findAllDependentFunctions(cn, fn);
|
||||
// add self and all dependent function declaration
|
||||
for (FunctionNode fNode : functionNodes) {
|
||||
if (dependentFunctions.contains(fNode.functionName)) {
|
||||
jsStr.append(fNode.plainText()).append("\n");
|
||||
}
|
||||
}
|
||||
// load necessary Node.js libraries
|
||||
jsStr.append("var fs = require('fs');\n" + "var crypto = require('crypto');\n" + "var sm2 = require('sm-crypto').sm2;\n");
|
||||
// load Global variables and arguments from files
|
||||
jsStr.append("let rawGlobal = fs.readFileSync('global.json').toString();\n" + "let Global = JSON.parse(rawGlobal);\n");
|
||||
jsStr.append("let rawArg = fs.readFileSync('arg.json').toString();\n" + "let jsonArg = JSON.parse(rawArg);\n" + "let requester = jsonArg.requester;\n" + "let arg = jsonArg.arg;\n");
|
||||
jsStr.append("let srcStr = fs.readFileSync('contract.js').toString();\n");
|
||||
// verify signatures and decrypt all confidential variables Important!!!!!
|
||||
jsStr.append("for (var k in Global) {\n" + " if (Global.hasOwnProperty(k)) {\n" + " if (k.startsWith('conf_')) {\n" + " let sig = Global[k].signature;\n" + " let pubKey = Global[k].owner;\n" + " let verifyResult = sm2.doVerifySignature(srcStr, sig, pubKey);\n" + " if (verifyResult) {\n" + " let newKey = k.substring(5);\n" + " let decKey = Buffer.from(process.env['KEY_'+pubKey.substring(0,10).toUpperCase()], 'hex');\n" + " let decIv = Buffer.from(Global[k].iv, 'hex');\n" + " let cipherText = Buffer.from(Global[k].cipherText, 'hex');\n" + " let decipher = crypto.createDecipheriv('aes-256-cbc', decKey, decIv);\n" + " let decrypted = decipher.update(cipherText);\n" + " decrypted = Buffer.concat([decrypted, decipher.final()]);\n" + " let plaintext = decrypted.toString();\n" + " Global[newKey] = plaintext;\n" + " }\n" + " }\n" + " }\n" + "}\n");
|
||||
// call function
|
||||
jsStr.append("var ret = ").append(fn.functionName).append("(arg, requester, null);\n");
|
||||
// TODO: encrypt all confidential variables so state can be updated in confidential function @shujunyi
|
||||
// encrypt return value and write to a file
|
||||
jsStr.append("var retStr = JSON.stringify(ret);\n" + "var key = Buffer.from(process.env['KEY_'+requester.substring(0,10).toUpperCase()], 'hex');\n" + "var iv = crypto.randomBytes(16);\n" + "let cipher = crypto.createCipheriv('aes-256-cbc', key, iv); \n" + "let encRet = cipher.update(retStr);\n" + "encRet = Buffer.concat([encRet, cipher.final()]);\n" + "let result = {iv: iv.toString('hex'), encryptedData: encRet.toString('hex')};\n" + "let resultStr = JSON.stringify(result);\n" + "fs.writeFileSync('result.json', resultStr);\n");
|
||||
// put script into Global so owner can send it and collect signatures
|
||||
Object som = ScriptObjectMirror.wrap(jsStr.toString(), global);
|
||||
globalVars.put("src_" + fn.functionName, som);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void copyTemplateToDestination(ContractRequest input) {
|
||||
String dest = CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID();
|
||||
File srcDir = new File(CONFIDENTIAL_TEMPLATE_PATH);
|
||||
File destDir = new File(dest);
|
||||
try {
|
||||
FileUtils.copyDirectory(srcDir, destDir);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public static void dumpScriptAndStates(
|
||||
Invocable engine,
|
||||
FunctionNode functionNode,
|
||||
ContractRequest input,
|
||||
ScriptObjectMirror globalVars)
|
||||
throws IOException, ScriptException, NoSuchMethodException {
|
||||
Map<String, Object> globalMap = (Map<String, Object>) convertIntoJavaObject(globalVars);
|
||||
String dest = CONFIDENTIAL_SCRIPT_PATH + File.separator + input.getRequestID();
|
||||
// dump script
|
||||
String jsStr = globalMap.remove("src_" + functionNode.functionName).toString();
|
||||
String scriptPath = dest + File.separator + "contract.js";
|
||||
BufferedWriter writer = new BufferedWriter(new FileWriter(scriptPath));
|
||||
writer.write(jsStr);
|
||||
writer.close();
|
||||
// dump global variables
|
||||
globalMap.remove("Resources");
|
||||
String globalStr = JsonUtil.toJson(globalMap);
|
||||
String globalPath = dest + File.separator + "global.json";
|
||||
writer = new BufferedWriter(new FileWriter(globalPath));
|
||||
writer.write(globalStr);
|
||||
writer.close();
|
||||
// dump arg and requester
|
||||
Map<String, Object> argMap = new HashMap<>();
|
||||
argMap.put("arg", input.getArg());
|
||||
argMap.put("requester", input.getRequester());
|
||||
String argStr = JsonUtil.toJson(argMap);
|
||||
String argPath = dest + File.separator + "arg.json";
|
||||
writer = new BufferedWriter(new FileWriter(argPath));
|
||||
writer.write(argStr);
|
||||
writer.close();
|
||||
// generate manifest
|
||||
String manifestStr = generateGrapheneManifestStr(engine, input);
|
||||
String manifestPath = dest + File.separator + "nodejs.manifest.template";
|
||||
writer = new BufferedWriter(new FileWriter(manifestPath));
|
||||
writer.write(manifestStr);
|
||||
writer.close();
|
||||
}
|
||||
|
||||
private static Set<String> findAllDependentFunctions(ContractNode cn, FunctionNode fn) {
|
||||
Set<String> dependentFunctions = fn.getDependentFunctions();
|
||||
for (String functionName : dependentFunctions) {
|
||||
for (FunctionNode functionNode : cn.getFunctions()) {
|
||||
if (functionNode.functionName.equals(functionName)) {
|
||||
dependentFunctions.addAll(findAllDependentFunctions(cn, functionNode));
|
||||
}
|
||||
}
|
||||
}
|
||||
dependentFunctions.add(fn.functionName);
|
||||
return dependentFunctions;
|
||||
}
|
||||
|
||||
private static String generateGrapheneManifestStr(Invocable engine, ContractRequest input) throws ScriptException, NoSuchMethodException {
|
||||
String manifestStr = "# Nodejs manifest file example\n" +
|
||||
"#\n" +
|
||||
"# This manifest was prepared and tested on Ubuntu 18.04.\n" +
|
||||
"\n" +
|
||||
"loader.argv0_override = \"nodejs\"\n" +
|
||||
"\n" +
|
||||
"# LibOS layer library of Graphene. There is currently only one implementation,\n" +
|
||||
"# so it is always set to libsysdb.so.\n" +
|
||||
"loader.preload = \"file:$(GRAPHENEDIR)/Runtime/libsysdb.so\"\n" +
|
||||
"\n" +
|
||||
"# Show/hide debug log of Graphene ('inline' or 'none' respectively).\n" +
|
||||
"loader.debug_type = \"$(GRAPHENEDEBUG)\"\n" +
|
||||
"\n" +
|
||||
"# Read application arguments directly from the command line. Don't use this on production!\n" +
|
||||
"loader.insecure__use_cmdline_argv = 1\n" +
|
||||
"\n" +
|
||||
"# Specify paths to search for libraries. The usual LD_LIBRARY_PATH syntax\n" +
|
||||
"# applies. Paths must be in-Graphene visible paths, not host-OS paths (i.e.,\n" +
|
||||
"# paths must be taken from fs.mount.xxx.path, not fs.mount.xxx.uri).\n" +
|
||||
"loader.env.LD_LIBRARY_PATH = \"/lib:/usr/lib:$(ARCH_LIBDIR):/usr/$(ARCH_LIBDIR):./\"\n" +
|
||||
"\n" +
|
||||
"# Mount host-OS directory to required libraries (in 'uri') into in-Graphene\n" +
|
||||
"# visible directory /lib (in 'path').\n" +
|
||||
"fs.mount.lib.type = \"chroot\"\n" +
|
||||
"fs.mount.lib.path = \"/lib\"\n" +
|
||||
"fs.mount.lib.uri = \"file:$(GRAPHENEDIR)/Runtime\"\n" +
|
||||
"\n" +
|
||||
"fs.mount.lib2.type = \"chroot\"\n" +
|
||||
"fs.mount.lib2.path = \"$(ARCH_LIBDIR)\"\n" +
|
||||
"fs.mount.lib2.uri = \"file:$(ARCH_LIBDIR)\"\n" +
|
||||
"\n" +
|
||||
"#fs.mount.lib3.type = \"chroot\"\n" +
|
||||
"#fs.mount.lib3.path = \"/usr/$(ARCH_LIBDIR)\"\n" +
|
||||
"#fs.mount.lib3.uri = \"file:/usr/$(ARCH_LIBDIR)\"\n" +
|
||||
"\n" +
|
||||
"fs.mount.usr.type = \"chroot\"\n" +
|
||||
"fs.mount.usr.path = \"/usr\"\n" +
|
||||
"fs.mount.usr.uri = \"file:/usr\"\n" +
|
||||
"\n" +
|
||||
"# Host-level directory to NSS files required by Glibc + NSS libs\n" +
|
||||
"fs.mount.etc.type = \"chroot\"\n" +
|
||||
"fs.mount.etc.path = \"/etc\"\n" +
|
||||
"fs.mount.etc.uri = \"file:/etc\"\n" +
|
||||
"\n" +
|
||||
"# Workload needs to create temporary files\n" +
|
||||
"fs.mount.tmp.type = \"chroot\"\n" +
|
||||
"fs.mount.tmp.path = \"/tmp\"\n" +
|
||||
"fs.mount.tmp.uri = \"file:/tmp\"\n" +
|
||||
"\n" +
|
||||
"# Set enclave size to 2GB; NodeJS expects around 1.7GB of heap on startup,\n" +
|
||||
"# see e.g. https://github.com/nodejs/node/issues/13018.\n" +
|
||||
"# Recall that SGX v1 requires to specify enclave size at enclave creation time.\n" +
|
||||
"sgx.enclave_size = \"2G\"\n" +
|
||||
"\n" +
|
||||
"# Set maximum number of in-enclave threads (somewhat arbitrarily) to 8. Recall\n" +
|
||||
"# that SGX v1 requires to specify the maximum number of simultaneous threads at\n" +
|
||||
"# enclave creation time.\n" +
|
||||
"sgx.thread_num = 16\n" +
|
||||
"\n" +
|
||||
"# Specify all libraries used by Node.js and its dependencies (including all libs\n" +
|
||||
"# which can be loaded at runtime via dlopen).\n" +
|
||||
"sgx.trusted_files.ld = \"file:$(GRAPHENEDIR)/Runtime/ld-linux-x86-64.so.2\"\n" +
|
||||
"sgx.trusted_files.libc = \"file:$(GRAPHENEDIR)/Runtime/libc.so.6\"\n" +
|
||||
"sgx.trusted_files.libm = \"file:$(GRAPHENEDIR)/Runtime/libm.so.6\"\n" +
|
||||
"sgx.trusted_files.libdl = \"file:$(GRAPHENEDIR)/Runtime/libdl.so.2\"\n" +
|
||||
"sgx.trusted_files.librt = \"file:$(GRAPHENEDIR)/Runtime/librt.so.1\"\n" +
|
||||
"sgx.trusted_files.libutil = \"file:$(GRAPHENEDIR)/Runtime/libutil.so.1\"\n" +
|
||||
"sgx.trusted_files.libpthread = \"file:$(GRAPHENEDIR)/Runtime/libpthread.so.0\"\n" +
|
||||
"sgx.trusted_files.libnssdns = \"file:$(GRAPHENEDIR)/Runtime/libnss_dns.so.2\"\n" +
|
||||
"sgx.trusted_files.libresolv = \"file:$(GRAPHENEDIR)/Runtime/libresolv.so.2\"\n" +
|
||||
"\n" +
|
||||
"sgx.trusted_files.libstdc = \"file:/usr/$(ARCH_LIBDIR)/libstdc++.so.6\"\n" +
|
||||
"sgx.trusted_files.libgccs = \"file:$(ARCH_LIBDIR)/libgcc_s.so.1\"\n" +
|
||||
"sgx.trusted_files.libaptpkg = \"file:/usr/$(ARCH_LIBDIR)/libapt-pkg.so.5.0\"\n" +
|
||||
"sgx.trusted_files.liblz4 = \"file:/usr/$(ARCH_LIBDIR)/liblz4.so.1\"\n" +
|
||||
"sgx.trusted_files.libsystemd = \"file:$(ARCH_LIBDIR)/libsystemd.so.0\"\n" +
|
||||
"sgx.trusted_files.libselinux = \"file:$(ARCH_LIBDIR)/libselinux.so.1\"\n" +
|
||||
"sgx.trusted_files.libgcrypt = \"file:$(ARCH_LIBDIR)/libgcrypt.so.20\"\n" +
|
||||
"sgx.trusted_files.libpcre = \"file:$(ARCH_LIBDIR)/libpcre.so.3\"\n" +
|
||||
"sgx.trusted_files.libgpgerror = \"file:$(ARCH_LIBDIR)/libgpg-error.so.0\"\n" +
|
||||
"sgx.trusted_files.libexpat = \"file:$(ARCH_LIBDIR)/libexpat.so.1\"\n" +
|
||||
"sgx.trusted_files.libz = \"file:$(ARCH_LIBDIR)/libz.so.1\"\n" +
|
||||
"sgx.trusted_files.libz2 = \"file:$(ARCH_LIBDIR)/libbz2.so.1.0\"\n" +
|
||||
"sgx.trusted_files.liblzma = \"file:$(ARCH_LIBDIR)/liblzma.so.5\"\n" +
|
||||
"sgx.trusted_files.libmpdec = \"file:/usr/$(ARCH_LIBDIR)/libmpdec.so.2\"\n" +
|
||||
"\n" +
|
||||
"# Name Service Switch (NSS) libraries (Glibc dependencies)\n" +
|
||||
"sgx.trusted_files.libnssfiles = \"file:$(ARCH_LIBDIR)/libnss_files.so.2\"\n" +
|
||||
"sgx.trusted_files.libnsscompat = \"file:$(ARCH_LIBDIR)/libnss_compat.so.2\"\n" +
|
||||
"sgx.trusted_files.libnssnis = \"file:$(ARCH_LIBDIR)/libnss_nis.so.2\"\n" +
|
||||
"sgx.trusted_files.libnsl = \"file:$(ARCH_LIBDIR)/libnsl.so.1\"\n" +
|
||||
"sgx.trusted_files.libnssmyhostname = \"file:$(ARCH_LIBDIR)/libnss_myhostname.so.2\"\n" +
|
||||
"sgx.trusted_files.libnssmdns = \"file:$(ARCH_LIBDIR)/libnss_mdns4_minimal.so.2\"\n" +
|
||||
"\n" +
|
||||
"# Scratch space\n" +
|
||||
"sgx.allowed_files.tmp = \"file:/tmp\"\n" +
|
||||
"\n" +
|
||||
"# APT config files\n" +
|
||||
"sgx.allowed_files.aptconfd = \"file:/etc/apt/apt.conf.d\"\n" +
|
||||
"sgx.allowed_files.aptconf = \"file:/etc/apt/apt.conf\"\n" +
|
||||
"sgx.allowed_files.apport = \"file:/etc/default/apport\"\n" +
|
||||
"\n" +
|
||||
"# Name Service Switch (NSS) files (Glibc reads these files)\n" +
|
||||
"sgx.allowed_files.nsswitch = \"file:/etc/nsswitch.conf\"\n" +
|
||||
"sgx.allowed_files.group = \"file:/etc/group\"\n" +
|
||||
"sgx.allowed_files.passwd = \"file:/etc/passwd\"\n" +
|
||||
"\n" +
|
||||
"# DNS hostname resolution files (Glibc reads these files)\n" +
|
||||
"sgx.allowed_files.hostconf = \"file:/etc/host.conf\"\n" +
|
||||
"sgx.allowed_files.hosts = \"file:/etc/hosts\"\n" +
|
||||
"sgx.allowed_files.gaiconf = \"file:/etc/gai.conf\"\n" +
|
||||
"sgx.allowed_files.resolv = \"file:/etc/resolv.conf\"\n" +
|
||||
"\n" +
|
||||
"sgx.allowed_files.openssl = \"file:/etc/ssl/openssl.cnf\"\n" +
|
||||
"\n" +
|
||||
"# System's file system table\n" +
|
||||
"sgx.allowed_files.fstab = \"file:/etc/fstab\"\n" +
|
||||
"\n" +
|
||||
"$(NODEJS_TRUSTED_LIBS)\n" +
|
||||
"\n" +
|
||||
"# JavaScript (trusted)\n" +
|
||||
"sgx.allowed_files.smlib = \"file:node_modules\"\n" +
|
||||
"sgx.trusted_files.npminfo = \"file:package.json\"\n" +
|
||||
"sgx.trusted_files.contract = \"file:contract.js\"\n" +
|
||||
"sgx.trusted_files.globaljson = \"file:global.json\"\n" +
|
||||
"sgx.trusted_files.argjson = \"file:arg.json\"\n" +
|
||||
"\n" +
|
||||
"sys.insecure__allow_eventfd = 1\n" +
|
||||
"\n" +
|
||||
"sgx.remote_attestation = 1\n" +
|
||||
"\n" +
|
||||
"loader.env.LD_PRELOAD = \"libsecret_prov_attest.so\"\n" +
|
||||
"loader.env.SECRET_PROVISION_CONSTRUCTOR = \"1\"\n" +
|
||||
"loader.env.SECRET_PROVISION_SET_PF_KEY = \"1\"\n" +
|
||||
"loader.env.SECRET_PROVISION_CA_CHAIN_PATH = \"certs/test-ca-sha256.crt\"\n" +
|
||||
"loader.env.SECRET_PROVISION_SERVERS = \"localhost:4433\"\n" +
|
||||
"\n" +
|
||||
"sgx.trusted_files.libsecretprovattest = \"file:libsecret_prov_attest.so\"\n" +
|
||||
"sgx.trusted_files.cachain = \"file:certs/test-ca-sha256.crt\"\n" +
|
||||
"\n" +
|
||||
"# Specify your SPID and linkable/unlinkable attestation policy\n" +
|
||||
"sgx.ra_client_spid = \"DF3A8BA098E93F66CC64E8A215E98333\"\n" +
|
||||
"sgx.ra_client_linkable = 0\n";
|
||||
// add secret servers
|
||||
manifestStr += "loader.env.SECRET_PROVISION_CC_SERVERS = ";
|
||||
Object resultStr = engine.invokeFunction(
|
||||
"getAllSecret",
|
||||
"",
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
Map<String, String> resultMap = JsonUtil.fromJson(resultStr.toString(), MapType);
|
||||
Map<String, String> serverMap = JsonUtil.fromJson(resultMap.get("result"), MapType);
|
||||
List<String> entries = new ArrayList<>();
|
||||
for (Map.Entry<String, String> entry : serverMap.entrySet()) {
|
||||
String key = entry.getKey();
|
||||
String server = entry.getValue();
|
||||
String envVar = "KEY_" + key.substring(0, 10).toUpperCase();
|
||||
entries.add(envVar + "=" + server);
|
||||
}
|
||||
manifestStr += "\"" + String.join(";", entries) + "\"";
|
||||
return manifestStr;
|
||||
}
|
||||
|
||||
private static Object convertIntoJavaObject(Object scriptObj) {
|
||||
if (scriptObj instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror scriptObjectMirror = (ScriptObjectMirror) scriptObj;
|
||||
if (scriptObjectMirror.isArray()) {
|
||||
List<Object> list = new ArrayList<>();
|
||||
for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
|
||||
list.add(convertIntoJavaObject(entry.getValue()));
|
||||
}
|
||||
return list;
|
||||
} else {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : scriptObjectMirror.entrySet()) {
|
||||
map.put(entry.getKey(), convertIntoJavaObject(entry.getValue()));
|
||||
}
|
||||
return map;
|
||||
}
|
||||
} else {
|
||||
return scriptObj;
|
||||
}
|
||||
}
|
||||
}
|
||||
884
src/main/java/org/bdware/sc/engine/DesktopEngine.java
Normal file
884
src/main/java/org/bdware/sc/engine/DesktopEngine.java
Normal file
@@ -0,0 +1,884 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.analysis.BasicBlock;
|
||||
import org.bdware.analysis.CFGraph;
|
||||
import org.bdware.analysis.gas.Evaluates;
|
||||
import org.bdware.analysis.gas.PPCount;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.ContractResult.Status;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.boundry.Resources;
|
||||
import org.bdware.sc.boundry.utils.UtilRegistry;
|
||||
import org.bdware.sc.encrypt.HardwareInfo;
|
||||
import org.bdware.sc.encrypt.HardwareInfo.OSType;
|
||||
import org.bdware.sc.event.Event;
|
||||
import org.bdware.sc.event.REvent;
|
||||
import org.bdware.sc.event.REvent.REventSemantics;
|
||||
import org.bdware.sc.node.*;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.trace.ProgramPointCounter;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.objectweb.asm.ClassReader;
|
||||
import org.objectweb.asm.tree.MethodNode;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.*;
|
||||
|
||||
import javax.script.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
public class DesktopEngine extends JSEngine {
|
||||
private static final String ScriptFileName = "contract_main.yjs";
|
||||
private static final Logger LOGGER = LogManager.getLogger(DesktopEngine.class);
|
||||
public static boolean _with_init_script = true;
|
||||
// static String script = "";
|
||||
public NashornScriptEngine engine;
|
||||
public SyncMechUtil syncUtil;
|
||||
public boolean recovering; // 如果正在通过trace、trans恢复,设置为true,此时即使是StableMode也不记录
|
||||
Resources resources;
|
||||
// Class<?> clz;
|
||||
// byte[] stub;
|
||||
YJSClassLoader classLoader;
|
||||
private ContractNode cn;
|
||||
private Global global;
|
||||
// private Object obj;
|
||||
// private SimpleScriptContext simpleContext;
|
||||
// private String traceDir;
|
||||
private ContractProcess.Logger tracePS = null;
|
||||
private Contract contract;
|
||||
|
||||
public DesktopEngine() {
|
||||
startEngine();
|
||||
}
|
||||
|
||||
public DesktopEngine(ContractManifest manifest, String zipPath, Contract contract) {
|
||||
File zipFile = new File(zipPath);
|
||||
String dirName = zipFile.getName().replaceAll(".zip$", "").replaceAll(".ypk$", "");
|
||||
File traceDirFile = new File(zipFile.getParent(), dirName);
|
||||
|
||||
this.contract = contract;
|
||||
if (!traceDirFile.exists()) {
|
||||
// traceDirFile.mkdirs();
|
||||
}
|
||||
// traceDir = traceDirFile.getAbsolutePath();
|
||||
startEngine();
|
||||
}
|
||||
|
||||
public static void applyWithGlobal(ScriptFunction script, Global global, Object... obj) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
// System.out.println("[DesktopEngine]" + script.getName() + " -->\n" +
|
||||
// script.safeToString());
|
||||
ScriptRuntime.apply(script, global, obj);
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setRecovering(boolean b) {
|
||||
recovering = b;
|
||||
}
|
||||
|
||||
public NashornScriptEngine getNashornEngine() {
|
||||
return engine;
|
||||
}
|
||||
|
||||
public Global getDesktopGlobal() {
|
||||
return global;
|
||||
}
|
||||
|
||||
public YJSClassLoader getClassLoad() {
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public void redirectTracePS(ContractProcess.Logger ps) {
|
||||
TraceType.ps = tracePS = (ps);
|
||||
if (ps instanceof TraceMethod) {
|
||||
TraceType.mTracer = (TraceMethod) ps;
|
||||
}
|
||||
}
|
||||
|
||||
private void startEngine() {
|
||||
try {
|
||||
syncUtil = new SyncMechUtil(this);
|
||||
ClassLoader ccl = Thread.currentThread().getContextClassLoader();
|
||||
ccl = (ccl == null) ? NashornScriptEngineFactory.class.getClassLoader() : ccl;
|
||||
String[] args = new String[]{"--loader-per-compile=false", "-strict=false"};
|
||||
classLoader = new YJSClassLoader(ccl, new YJSFilter());
|
||||
engine =
|
||||
(NashornScriptEngine)
|
||||
new NashornScriptEngineFactory()
|
||||
.getScriptEngine(
|
||||
args, // "--print-ast",
|
||||
// "true",
|
||||
// "-d=/Users/huaqiancai/Downloads/dumpedClz",
|
||||
// "--trace-callsites=enterexit"
|
||||
// "--log=methodhandles:all",
|
||||
// fields:all,
|
||||
// "--print-parse", "true" "--print-code",
|
||||
// fields:finest
|
||||
classLoader);
|
||||
|
||||
Context.TRACEIF = false;
|
||||
// engine = (NashornScriptEngine) new
|
||||
// NashornScriptEngineFactory().getScriptEngine(new YJSFilter());
|
||||
if (_with_init_script) {
|
||||
InputStream in =
|
||||
DesktopEngine.class
|
||||
.getClassLoader()
|
||||
.getResourceAsStream("org/bdware/sc/engine/yancloud_desktop.js");
|
||||
assert in != null;
|
||||
InputStreamReader streamReader = new InputStreamReader(in);
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
"org/bdware/sc/engine/yancloud_desktop.js",
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(streamReader);
|
||||
}
|
||||
global = engine.getNashornGlobal();
|
||||
JavaScriptEntry.currentEngine = engine;
|
||||
JavaScriptEntry.currentSyncUtil = syncUtil;
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void initStubClasses() {
|
||||
UtilRegistry.defineUtilClass(classLoader);
|
||||
}
|
||||
|
||||
public void setPermission(List<Permission> setPermission) {
|
||||
initStubClasses();
|
||||
try {
|
||||
StringBuilder yancloud_desktop = new StringBuilder();
|
||||
List<String> permissionStub = Permission.allName();
|
||||
for (Permission permission : setPermission) {
|
||||
yancloud_desktop.append(UtilRegistry.getInitStr(permission.name(), true));
|
||||
permissionStub.remove(permission.name());
|
||||
}
|
||||
for (String str : permissionStub) {
|
||||
yancloud_desktop.append(UtilRegistry.getInitStr(str, false));
|
||||
}
|
||||
// LOGGER.debug("[initScript] " + yancloud_desktop);
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
yancloud_desktop.toString(),
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
engine.eval(yancloud_desktop.toString());
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// byte[]中是字节码
|
||||
public Map<String, byte[]> dumpClass() {
|
||||
ScriptLoader loader = engine.getNashornContext().getScriptLoader();
|
||||
Map<String, byte[]> clzCache = loader.getClzCache();
|
||||
Map<String, byte[]> ret = new HashMap<>(clzCache);
|
||||
// for (String str : clzCache.keySet()) {
|
||||
// System.out.println("===ScriptClzName:" + str);
|
||||
// }
|
||||
StructureLoader sLoader = (StructureLoader) (engine.getNashornContext().getStructLoader());
|
||||
clzCache = sLoader.getClzCache();
|
||||
// for (String str : clzCache.keySet()) {
|
||||
// System.out.println("===StructureClzName:" + str);
|
||||
// }
|
||||
ret.putAll(clzCache);
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void registerResource(Resources resources) {
|
||||
Invocable cal = engine;
|
||||
this.resources = resources;
|
||||
try {
|
||||
cal.invokeFunction("defineProp", "Resources", resources);
|
||||
} catch (NoSuchMethodException | ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public Resources getResources() {
|
||||
return this.resources;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ContractResult loadContract(
|
||||
Contract contract, ContractNode contractNode, boolean isInsnLimit) {
|
||||
LOGGER.info("loadContract isInsnLimit:" + isInsnLimit);
|
||||
cn = contractNode;
|
||||
engine.getContext()
|
||||
.setAttribute(ScriptEngine.FILENAME, ScriptFileName, ScriptContext.ENGINE_SCOPE);
|
||||
try {
|
||||
setPermission(cn.getPermission());
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
for (FunctionNode fun : contractNode.getFunctions())
|
||||
try {
|
||||
String str = fun.plainText();
|
||||
engine.getContext()
|
||||
.setAttribute(
|
||||
ScriptEngine.FILENAME,
|
||||
fun.getFileName(),
|
||||
ScriptContext.ENGINE_SCOPE);
|
||||
compileFunction(str, isInsnLimit);
|
||||
} catch (ScriptException e) {
|
||||
return wrapperException(e, fun);
|
||||
} catch (Exception e) {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
e.printStackTrace(new PrintStream(bo));
|
||||
e.printStackTrace();
|
||||
return new ContractResult(Status.Error, new JsonPrimitive(bo.toString()));
|
||||
}
|
||||
LOGGER.debug(JsonUtil.toJson(contractNode.events));
|
||||
for (String event : contractNode.events.keySet()) {
|
||||
try {
|
||||
String str;
|
||||
REventSemantics semantics = contractNode.events.get(event);
|
||||
if (REventSemantics.AT_LEAST_ONCE.equals(semantics)) {
|
||||
str =
|
||||
String.format(
|
||||
"function %s(arg) { YancloudUtil.pubEvent(\"%s\", arg); }",
|
||||
event, event);
|
||||
} else {
|
||||
str =
|
||||
String.format(
|
||||
"function %s(arg) { YancloudUtil.pubEventConstraint(\"%s\", arg, \"%s\"); }",
|
||||
event, event, semantics.name());
|
||||
}
|
||||
compileFunction(str, false);
|
||||
str =
|
||||
String.format(
|
||||
"function %ss(arg0, arg1) { YancloudUtil.pubEventConstraint(\"%s\", arg0, arg1); }",
|
||||
event, event);
|
||||
compileFunction(str, false);
|
||||
} catch (ScriptException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
for (ClassNode cn : contractNode.getClzs()) {
|
||||
try {
|
||||
System.out.println(cn.plainText());
|
||||
// engine.eval(cn.plainText());
|
||||
} catch (Exception e) {
|
||||
// return wrapperException(e, cn.getFileName(), cn.getLine(),
|
||||
// cn.getPos());
|
||||
}
|
||||
}
|
||||
ScriptObjectMirror globalVars = (ScriptObjectMirror) engine.get("Global");
|
||||
ConfidentialContractUtil.generateConfidentialContract(cn, globalVars, global);
|
||||
ContractResult cResult =
|
||||
new ContractResult(Status.Success, new JsonPrimitive(contract.getPublicKey()));
|
||||
cResult.isInsnLimit = isInsnLimit;
|
||||
return cResult;
|
||||
}
|
||||
|
||||
// /**
|
||||
// * Load a contract into contract engine
|
||||
// *
|
||||
// * @param contractNode a contract node generated by YJS compiler
|
||||
// * @return whether contract is loaded successfully
|
||||
// */
|
||||
// @Override
|
||||
// public ContractResult loadContract(Contract contract, ContractNode contractNode) {
|
||||
// cn = contractNode;
|
||||
// engine.getContext()
|
||||
// .setAttribute(ScriptEngine.FILENAME, ScriptFileName,
|
||||
// ScriptContext.ENGINE_SCOPE);
|
||||
// try {
|
||||
// setPermission(cn.getPermission());
|
||||
// } catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// for (FunctionNode fun : cn.getFunctions()) {
|
||||
// try {
|
||||
// String str = fun.plainText();
|
||||
// engine.getContext()
|
||||
// .setAttribute(
|
||||
// ScriptEngine.FILENAME,
|
||||
// fun.getFileName(),
|
||||
// ScriptContext.ENGINE_SCOPE);
|
||||
// Object scriptFunction = engine.eval(str);
|
||||
// ScriptObjectMirror sf = (ScriptObjectMirror) scriptFunction;
|
||||
// compileFunction(sf, fun.getLogTypes().contains(LogType.Branch));
|
||||
// } catch (ScriptException e) {
|
||||
// return wrapperException(e, fun);
|
||||
// } catch (Exception e) {
|
||||
// ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
// e.printStackTrace(new PrintStream(bo));
|
||||
// e.printStackTrace();
|
||||
// return new ContractResult(Status.Error, new JsonPrimitive(bo.toString()));
|
||||
// }
|
||||
// }
|
||||
// for (String event : cn.events) {
|
||||
// String str =
|
||||
// "function "
|
||||
// + event
|
||||
// + "(arg){ return YancloudUtil.pubEvent(\""
|
||||
// + event
|
||||
// + "\",arg);}";
|
||||
//
|
||||
// try {
|
||||
// Object scriptFunction = engine.eval(str);
|
||||
// ScriptObjectMirror sf = (ScriptObjectMirror) scriptFunction;
|
||||
// compileFunction(sf, false);
|
||||
// } catch (ScriptException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// for (ClassNode classNode : cn.getClzs()) {
|
||||
// try {
|
||||
// System.out.println(classNode.plainText());
|
||||
// // engine.eval(cn.plainText());
|
||||
// } catch (Exception e) {
|
||||
// // return wrapperException(e, cn.getFileName(), cn.getLine(),
|
||||
// // cn.getPos());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// // dump confidential functions and corresponding dependent functions to a String in
|
||||
// Global
|
||||
// // variable.
|
||||
// // The String will be passed to collect signature.
|
||||
//
|
||||
// return new ContractResult(Status.Success, new JsonPrimitive(""));
|
||||
// }
|
||||
private void compileFunction(ScriptObjectMirror sf, boolean instrumentBranch) {
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != global);
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(global);
|
||||
}
|
||||
if (instrumentBranch) {
|
||||
Context.TRACEIF = true;
|
||||
Context.TRACEMETHOD = true;
|
||||
}
|
||||
sf.compileScriptFunction();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (globalChanged) Context.setGlobal(oldGlobal);
|
||||
Context.TRACEIF = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void compileFunction(String snippet, boolean instrumentBranch) throws ScriptException {
|
||||
compileFunction((ScriptObjectMirror) engine.eval(snippet), instrumentBranch);
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized ContractResult executeContract(ContractRequest input) {
|
||||
ContractProcess.Logger previous = this.getTracePS();
|
||||
ByteArrayOutputStream bo = null;
|
||||
if (syncUtil.startFlag && syncUtil.currType == SyncType.Trace && !recovering) {
|
||||
syncUtil.traceRecordUtil.startNext();
|
||||
} else if (syncUtil.startFlag && syncUtil.currType == SyncType.Trans && !recovering) {
|
||||
if (input.needSeq) {
|
||||
syncUtil.transRecordUtil.startNext(input.getAction(), input.getArg(), input.seq);
|
||||
} else {
|
||||
syncUtil.transRecordUtil.startNext(input.getAction(), input.getArg());
|
||||
}
|
||||
}
|
||||
// TODO remove this in executeContract, using getFunctionNodes in ContractManger instead.
|
||||
if (input.getAction().equals("getFunctionNodes")) {
|
||||
return getFunctionNodes();
|
||||
}
|
||||
JavaScriptEntry.msgList = new ArrayList<>();
|
||||
FunctionNode fun = cn.getFunction(input.getAction());
|
||||
ProgramPointCounter ppc = null;
|
||||
try {
|
||||
if (fun.getCost() != null && fun.getCost().isCountGas()) {
|
||||
List<String> functions = new ArrayList<>();
|
||||
for (FunctionNode fn : cn.getFunctions()) {
|
||||
if (fn.isExport()) {
|
||||
functions.add(fn.functionName);
|
||||
}
|
||||
}
|
||||
int functionIndex = functions.indexOf(input.getAction());
|
||||
// TODO calculate ppCountMap at loading time?
|
||||
HashMap<String, Long> ppCountMap = evaluatesAnalysis(input.getAction(), functions);
|
||||
Long extraGas = getExtraGas(fun.getCost().getExtraGas(), input);
|
||||
bo = new ByteArrayOutputStream();
|
||||
ppc =
|
||||
new ProgramPointCounter(
|
||||
bo,
|
||||
previous.getCp(),
|
||||
Long.MAX_VALUE,
|
||||
functionIndex,
|
||||
input.getGasLimit(),
|
||||
extraGas,
|
||||
input.getAction(),
|
||||
ppCountMap);
|
||||
this.redirectTracePS(ppc);
|
||||
}
|
||||
Invocable cal = engine;
|
||||
if (fun.isExport()
|
||||
// if the function has been registered as event handler
|
||||
|| (fun.isHandler()
|
||||
&& (input.getRequester().length() == 40
|
||||
|| input.getRequester().equals("event")))) {
|
||||
Object ret = null;
|
||||
// long start = System.currentTimeMillis();
|
||||
|
||||
for (AnnotationHook handler : fun.beforeExecutionAnnotations()) {
|
||||
|
||||
ret = handler.handle(input, this, ret);
|
||||
}
|
||||
// actually invoke!
|
||||
if (ret == null) {
|
||||
ret =
|
||||
cal.invokeFunction(
|
||||
input.getAction(),
|
||||
(fun.isHandler()
|
||||
? JsonUtil.fromJson(input.getArg(), Event.class)
|
||||
: input.getArg()),
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
}
|
||||
for (AnnotationHook handler : fun.afterExecutionAnnotations()) {
|
||||
//Mask在after裏面
|
||||
//System.out.println("afterHook"+contract.Mask);
|
||||
|
||||
ret = handler.handle(input, this, ret);
|
||||
}
|
||||
//System.out.println("[DesktopEngine MaskConfig]"+ContractProcess.instance.getProjectConfig().getMaskConfig().config.toString());
|
||||
ContractResult contractRes = new ContractResult(Status.Success, (JsonElement) ret);
|
||||
if (ppc != null) {
|
||||
contractRes.extraGas = ppc.extraGas;
|
||||
contractRes.executionGas = ppc.cost;
|
||||
contractRes.totalGas = ppc.extraGas + ppc.cost;
|
||||
}
|
||||
if (bo != null) {
|
||||
contractRes.analysis = bo.toString();
|
||||
}
|
||||
|
||||
if (fun.getLogTypes().contains(LogType.Branch)) {
|
||||
contractRes.branch = tracePS.getOutputStr();
|
||||
}
|
||||
|
||||
List<REvent> msgList = JavaScriptEntry.msgList;
|
||||
JavaScriptEntry.msgList = null;
|
||||
if (!msgList.isEmpty()) {
|
||||
contractRes.events = msgList;
|
||||
contractRes.eventRelated = true;
|
||||
}
|
||||
|
||||
if (fun.isHandler() && input.getRequester().length() == 40) {
|
||||
contractRes.eventRelated = true;
|
||||
}
|
||||
if (syncUtil.startFlag && !recovering) {
|
||||
switch (syncUtil.currType) {
|
||||
case Trace:
|
||||
syncUtil.traceRecordUtil.eachFinish();
|
||||
break;
|
||||
case Trans:
|
||||
syncUtil.transRecordUtil.eachFinish();
|
||||
break;
|
||||
case Memory:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return contractRes;
|
||||
} else {
|
||||
// return new ContractResult(Status.Exception, "Action " + input.getAction() + "
|
||||
// is not exported!");
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive("Action " + input.getAction() + " is not exported!"));
|
||||
}
|
||||
|
||||
} catch (ScriptException e) {
|
||||
Throwable cause = e.getCause();
|
||||
e.printStackTrace();
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(extractException(e.getMessage(), extract(cn, cause))));
|
||||
} catch (Throwable e) {
|
||||
ByteArrayOutputStream bo1 = new ByteArrayOutputStream();
|
||||
PrintStream ps = new PrintStream(bo1);
|
||||
e.printStackTrace(ps);
|
||||
e.printStackTrace();
|
||||
if (e.getCause() != null && e.getCause() instanceof ScriptException) {
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(
|
||||
extractException(bo1.toString(), extract(cn, e.getCause()))));
|
||||
} else {
|
||||
return new ContractResult(
|
||||
Status.Exception,
|
||||
new JsonPrimitive(extractException(bo1.toString(), extract(cn, e))));
|
||||
}
|
||||
} finally {
|
||||
this.redirectTracePS(previous);
|
||||
}
|
||||
}
|
||||
|
||||
private String extractException(String msg, List<String> stack) {
|
||||
int endIndex = Math.min(msg.indexOf("in"), msg.length());
|
||||
StringBuilder msb = new StringBuilder(msg.substring(0, endIndex));
|
||||
for (String str : stack) {
|
||||
msb.append("\n").append(str);
|
||||
}
|
||||
return msb.toString();
|
||||
}
|
||||
|
||||
private HashMap<String, Long> evaluatesAnalysis(String getFunction, List<String> functions) {
|
||||
// System.out.println("当前的function:" + getFunction);
|
||||
HashMap<String, CFGraph> CFGmap = new HashMap<>();
|
||||
HashMap<String, Long> ppCountMap = new HashMap<>();
|
||||
Map<String, byte[]> clzs = this.dumpClass();
|
||||
Map<String, MethodNode> methods = new HashMap<>();
|
||||
for (byte[] clz : clzs.values()) {
|
||||
org.objectweb.asm.tree.ClassNode classNode = new org.objectweb.asm.tree.ClassNode();
|
||||
ClassReader cr = new ClassReader(clz);
|
||||
cr.accept(classNode, ClassReader.EXPAND_FRAMES);
|
||||
for (MethodNode mn : classNode.methods) {
|
||||
methods.put(mn.name, mn);
|
||||
}
|
||||
}
|
||||
int flag = 0;
|
||||
for (String function : functions) {
|
||||
MethodNode mn = methods.get(function);
|
||||
if (mn != null) {
|
||||
CFGraph cfg =
|
||||
new CFGraph(mn) {
|
||||
@Override
|
||||
public BasicBlock getBasicBlock(int id) {
|
||||
return new BasicBlock(id);
|
||||
}
|
||||
};
|
||||
// cfg.printSelf();
|
||||
CFGmap.put(function, cfg);
|
||||
PPCount countFee = new PPCount(cfg, flag);
|
||||
|
||||
BasicBlock bb = cfg.getBasicBlockAt(0);
|
||||
countFee.dfs(cfg, bb);
|
||||
// System.out.println("[ppmap]:" + PPCount.ppMap);
|
||||
// System.out.println("[PPCount.branchCount]"+PPCount.branchCount);
|
||||
Evaluates feEvaluates = new Evaluates();
|
||||
feEvaluates.getGas(PPCount.branchCount);
|
||||
feEvaluates.getInsnGas(PPCount.ppMap);
|
||||
|
||||
PPCount.countFunction(function, Evaluates.map);
|
||||
ppCountMap = Evaluates.map;
|
||||
// System.out.println("+++++++" + PPCount.ppMap);
|
||||
flag++;
|
||||
}
|
||||
}
|
||||
/* for (Map.Entry<String, Long> map : PPCount.functionSumGas.entrySet()) {
|
||||
if (map.getKey().contains(getFunction) && map.getKey().contains("true")) {
|
||||
System.out.println("[合约方法pub中条件循环为true时:]" + map.getValue());
|
||||
} else if (map.getKey().contains(getFunction) && map.getKey().contains("false")) {
|
||||
System.out.println("[合约方法pub中条件循环为false时:]" + map.getValue());
|
||||
} else if (map.getKey().contains(getFunction)) {
|
||||
System.out.println("[合约方法pub中其他语句消耗:]" + map.getValue());
|
||||
}
|
||||
}*/
|
||||
return ppCountMap;
|
||||
}
|
||||
|
||||
private Long getExtraGas(String costFunction, ContractRequest input)
|
||||
throws ScriptException, NoSuchMethodException {
|
||||
if (costFunction == null || costFunction.equals("")) {
|
||||
return 0L;
|
||||
}
|
||||
Invocable cal = engine;
|
||||
Object ret =
|
||||
cal.invokeFunction(
|
||||
costFunction,
|
||||
input.getArg(),
|
||||
input.getRequester(),
|
||||
input.getRequesterDOI());
|
||||
if (ret != null && StringUtils.isNumeric(ret.toString())) {
|
||||
return Long.parseLong(ret.toString());
|
||||
} else {
|
||||
return 0L;
|
||||
}
|
||||
}
|
||||
|
||||
private ContractResult getFunctionNodes() {
|
||||
String msg = JsonUtil.toJson(cn.getFunctions());
|
||||
return new ContractResult(Status.Exception, new JsonPrimitive(msg));
|
||||
}
|
||||
|
||||
private void dump(Class<?> clz) {
|
||||
try {
|
||||
String name = clz.getCanonicalName().replace(".", "/") + ".class";
|
||||
System.out.println("DumpClzz:" + clz.getCanonicalName() + " -->" + name);
|
||||
name = "/Script.class";
|
||||
|
||||
InputStream input = clz.getClassLoader().getResourceAsStream(name);
|
||||
FileOutputStream fout =
|
||||
new FileOutputStream("./output/" + clz.getCanonicalName() + ".class");
|
||||
byte[] arr = new byte[1024];
|
||||
int l;
|
||||
assert input != null;
|
||||
while ((l = input.read(arr)) > 0) {
|
||||
fout.write(arr, 0, l);
|
||||
}
|
||||
fout.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private LinkedHashMap<?, ?> getClassCache(Context c) {
|
||||
try {
|
||||
Field f = c.getClass().getDeclaredField("classCache");
|
||||
f.setAccessible(true);
|
||||
Object classCache = f.get(c);
|
||||
return (LinkedHashMap<?, ?>) classCache;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private ContractResult wrapperException(ScriptException e, FunctionNode fun) {
|
||||
int line = fun.getLine();
|
||||
int pos = fun.getPos();
|
||||
StringBuilder content = new StringBuilder();
|
||||
String message = e.getMessage();
|
||||
message = message.replaceFirst("^[^:]*:[^:]*:[^ ]* ", "");
|
||||
int actLine = e.getLineNumber();
|
||||
if (actLine != -1) {
|
||||
actLine += line - 1;
|
||||
}
|
||||
message =
|
||||
message.replaceAll(
|
||||
"at line number " + e.getLineNumber(), "at line number " + (actLine));
|
||||
if (fun.getFileName() != null)
|
||||
message = message.replace("in contract_main.yjs", "in " + fun.getFileName());
|
||||
content.append(message);
|
||||
content.append("(");
|
||||
if (fun.functionName != null) content.append(fun.functionName);
|
||||
else content.append("contract_main.yjs");
|
||||
content.append(":");
|
||||
|
||||
content.append(actLine);
|
||||
content.append(":").append(pos).append(")");
|
||||
return new ContractResult(Status.Exception, new JsonPrimitive(content.toString()));
|
||||
}
|
||||
|
||||
private List<String> extract(ContractNode c, Throwable cause) {
|
||||
StackTraceElement[] stack = cause.getStackTrace();
|
||||
List<String> ret = new ArrayList<>();
|
||||
for (StackTraceElement element : stack) {
|
||||
|
||||
if (element == null || element.getFileName() == null) {
|
||||
continue;
|
||||
}
|
||||
String methodName = element.getMethodName();
|
||||
String fileName = element.getFileName();
|
||||
|
||||
if (fileName.endsWith(".java")) continue;
|
||||
if (c.isBundle()) {
|
||||
fileName = fixFile(c, methodName);
|
||||
}
|
||||
if (fileName.equals("--")) continue;
|
||||
ret.add(
|
||||
String.format(
|
||||
"at %s(%s:%d)",
|
||||
methodName,
|
||||
fileName,
|
||||
(fixLine(c, methodName) + element.getLineNumber())));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private String fixFile(ContractNode c, String methodName) {
|
||||
return c.queryFile(methodName);
|
||||
}
|
||||
|
||||
private int fixLine(ContractNode c, String methodName) {
|
||||
return c.queryLine(methodName) - 1;
|
||||
}
|
||||
|
||||
public Global getGlobal() {
|
||||
return engine.getNashornGlobal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script, ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader, ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(String script, Bindings n) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object eval(Reader reader, Bindings n) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void put(String key, Object value) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object get(String key) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings getBindings(int scope) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBindings(Bindings bindings, int scope) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bindings createBindings() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptContext getContext() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContext(ScriptContext context) {
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public ScriptEngineFactory getFactory() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void loadJar(ZipFile zf) {
|
||||
YJSClassLoader loader = getAppLoader();
|
||||
Enumeration<? extends ZipEntry> entries = zf.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
ZipEntry entry = entries.nextElement();
|
||||
if (entry.isDirectory()) {
|
||||
continue;
|
||||
}
|
||||
try {
|
||||
assert null != loader;
|
||||
if (entry.getName().endsWith(".jar")) {
|
||||
System.out.println("[DesktopEngine] loadJar:" + entry.getName());
|
||||
System.out.println("[DesktopEngine] classLoader:" + getClassLoad());
|
||||
|
||||
loader.loadJar(zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
if (entry.getName().endsWith(".so") || entry.getName().endsWith(".so.1")) {
|
||||
System.out.println("unzip library:" + entry.getName().replaceAll(".*/", ""));
|
||||
loader.unzipLibrary(
|
||||
zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
if (HardwareInfo.type == OSType.mac && entry.getName().endsWith(".dylib")) {
|
||||
System.out.println("unzip library:" + entry.getName().replaceAll(".*/", ""));
|
||||
loader.unzipLibrary(
|
||||
zf.getInputStream(entry), entry.getName().replaceAll(".*/", ""));
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (null != loader) {
|
||||
loader.loadLibraries();
|
||||
}
|
||||
}
|
||||
|
||||
private YJSClassLoader getAppLoader() {
|
||||
try {
|
||||
Field f = engine.getClass().getDeclaredField("nashornContext");
|
||||
f.setAccessible(true);
|
||||
Context c = (Context) f.get(engine);
|
||||
Method m = Context.class.getDeclaredMethod("getAppLoader");
|
||||
m.setAccessible(true);
|
||||
return (YJSClassLoader) m.invoke(c);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
public void initManifest(ContractManifest manifest) {
|
||||
// TODO Auto-generated method stub
|
||||
}
|
||||
|
||||
public ContractProcess.Logger getTracePS() {
|
||||
return tracePS;
|
||||
}
|
||||
|
||||
public Contract getContract() {
|
||||
return this.contract;
|
||||
}
|
||||
|
||||
public ProjectConfig getProjectConfig() {
|
||||
return ContractProcess.instance.getProjectConfig();
|
||||
}
|
||||
}
|
||||
101
src/main/java/org/bdware/sc/engine/JSONTool.java
Normal file
101
src/main/java/org/bdware/sc/engine/JSONTool.java
Normal file
@@ -0,0 +1,101 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import com.google.gson.*;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
public class JSONTool {
|
||||
private static Set<Object> recorded = null;
|
||||
|
||||
public static JsonElement copy(ScriptObjectMirror ret2) {
|
||||
recorded = new HashSet<>();
|
||||
JsonElement jsonElement = copyInternal(ret2);
|
||||
recorded.clear();
|
||||
;
|
||||
return jsonElement;
|
||||
}
|
||||
|
||||
private static JsonElement copyInternal(Object obj) {
|
||||
if (recorded.contains(obj)) return JsonNull.INSTANCE;
|
||||
if (obj == null) return JsonNull.INSTANCE;
|
||||
if (obj.getClass() == wrp.jdk.nashorn.internal.runtime.Undefined.class)
|
||||
return JsonNull.INSTANCE;
|
||||
if (obj.getClass() == ScriptObjectMirror.class) {
|
||||
recorded.add(obj);
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
if (som.isArray()) {
|
||||
JsonArray jarray = new JsonArray();
|
||||
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
try {
|
||||
if (Integer.parseInt(str) >= 0)
|
||||
jarray.add(copyInternal(som.getMember(str)));
|
||||
} catch (Exception e) {
|
||||
// System.out.println("[JSONTool] ignore key:"+str);
|
||||
}
|
||||
}
|
||||
return jarray;
|
||||
} else {
|
||||
JsonObject jo = new JsonObject();
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.add(str, copyInternal(som.getMember(str)));
|
||||
}
|
||||
return jo;
|
||||
}
|
||||
} else if (obj.getClass() == jdk.nashorn.api.scripting.ScriptObjectMirror.class) {
|
||||
recorded.add(obj);
|
||||
jdk.nashorn.api.scripting.ScriptObjectMirror som =
|
||||
(jdk.nashorn.api.scripting.ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
if (som.isArray()) {
|
||||
JsonArray jarray = new JsonArray();
|
||||
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
try {
|
||||
if (Integer.parseInt(str) >= 0)
|
||||
jarray.add(copyInternal(som.getMember(str)));
|
||||
} catch (Exception e) {
|
||||
// System.out.println("[JSONTool] ignore key:"+str);
|
||||
}
|
||||
}
|
||||
return jarray;
|
||||
} else {
|
||||
JsonObject jo = new JsonObject();
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.add(str, copyInternal(som.getMember(str)));
|
||||
}
|
||||
return jo;
|
||||
}
|
||||
} else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
return JsonNull.INSTANCE;
|
||||
} else if (obj instanceof Number) {
|
||||
return new JsonPrimitive((Number) obj);
|
||||
|
||||
} else if (obj instanceof String) {
|
||||
return new JsonPrimitive((String) obj);
|
||||
|
||||
} else if (obj instanceof Character) {
|
||||
return new JsonPrimitive((Character) obj);
|
||||
}
|
||||
if (obj instanceof Boolean) {
|
||||
return new JsonPrimitive((Boolean) obj);
|
||||
}
|
||||
return JsonNull.INSTANCE;
|
||||
}
|
||||
|
||||
public static JsonElement copy(jdk.nashorn.api.scripting.ScriptObjectMirror res) {
|
||||
recorded = new HashSet<>();
|
||||
JsonElement jsonElement = copyInternal(res);
|
||||
recorded.clear();
|
||||
;
|
||||
return jsonElement;
|
||||
}
|
||||
}
|
||||
301
src/main/java/org/bdware/sc/engine/SyncMechUtil.java
Normal file
301
src/main/java/org/bdware/sc/engine/SyncMechUtil.java
Normal file
@@ -0,0 +1,301 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.memory.MemoryDumpUtil;
|
||||
import org.bdware.sc.memory.MemoryRecoverUtil;
|
||||
import org.bdware.sc.redo.TransRecordUtil;
|
||||
import org.bdware.sc.redo.TransRecoverUtil;
|
||||
import org.bdware.sc.syncMech.SyncRecord;
|
||||
import org.bdware.sc.syncMech.SyncType;
|
||||
import org.bdware.sc.trace.TraceRecordUtil;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/*
|
||||
* 决策使用什么机制记录
|
||||
*/
|
||||
public class SyncMechUtil {
|
||||
private static final Logger LOGGER = LogManager.getLogger(SyncMechUtil.class);
|
||||
public AtomicInteger filedTrans; // 记录到文件中的trans数
|
||||
|
||||
public Boolean startFlag = false;
|
||||
public List<SyncRecord> syncRecords;
|
||||
// public List<SyncRecord> syncRecoverRecords;
|
||||
public SyncType currType;
|
||||
|
||||
public MemoryDumpUtil memoryDumpUtil;
|
||||
public MemoryRecoverUtil memoryRecoverUtil;
|
||||
public TraceRecordUtil traceRecordUtil;
|
||||
// public TraceRecoverUtil traceRecoverUtil;
|
||||
public TransRecordUtil transRecordUtil;
|
||||
public TransRecoverUtil transRecoverUtil;
|
||||
|
||||
public DesktopEngine engine;
|
||||
public String contractID;
|
||||
public String syncFileName;
|
||||
public String dir;
|
||||
public String memoryDir;
|
||||
public String traceDir;
|
||||
public String transDir;
|
||||
public String syncDir;
|
||||
public String crDir; // ContractRecord dir
|
||||
|
||||
public SyncMechUtil(DesktopEngine en) {
|
||||
this.engine = en;
|
||||
}
|
||||
|
||||
/*
|
||||
* 路径操作
|
||||
*/
|
||||
public void setDir(String str) {
|
||||
this.dir = str;
|
||||
String[] strs = str.split("/");
|
||||
this.contractID = strs[strs.length - 1];
|
||||
setMemoryDir(dir + "memory");
|
||||
setTraceDir(dir + "trace");
|
||||
setTransDir(dir + "trans");
|
||||
setSyncDir(dir + "sync");
|
||||
setCrDir(dir + "cr");
|
||||
}
|
||||
|
||||
public void setMemoryDir(String dir) {
|
||||
this.memoryDir = dir;
|
||||
File f = new File(memoryDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTraceDir(String dir) {
|
||||
this.traceDir = dir;
|
||||
File f = new File(traceDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setTransDir(String dir) {
|
||||
this.transDir = dir;
|
||||
File f = new File(transDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setSyncDir(String dir) {
|
||||
this.syncDir = dir;
|
||||
File f = new File(syncDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void setCrDir(String dir) {
|
||||
this.crDir = dir;
|
||||
File f = new File(crDir);
|
||||
if (!f.exists()) {
|
||||
f.mkdirs();
|
||||
}
|
||||
}
|
||||
|
||||
public void clearAllFiles() {
|
||||
File file = new File(syncDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(crDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(memoryDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(traceDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
file = new File(transDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* memory的操作
|
||||
* 无需startFlag就可以使用memory的操作
|
||||
*/
|
||||
public synchronized String dumpMemory(String path) {
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
return memoryDumpUtil.dumpMemory(path, true);
|
||||
}
|
||||
|
||||
public synchronized String dumpMemory(String path, boolean stateful) {
|
||||
LOGGER.info("dumpMemroy : stateful=" + stateful);
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
return memoryDumpUtil.dumpMemory(path, stateful);
|
||||
}
|
||||
|
||||
public synchronized String loadMemoryDump(String path) {
|
||||
if (memoryRecoverUtil == null)
|
||||
memoryRecoverUtil = new MemoryRecoverUtil(engine.engine, engine.resources);
|
||||
memoryRecoverUtil.loadMemory(path, true);
|
||||
return "success";
|
||||
}
|
||||
|
||||
public synchronized String loadMemoryDump(String path, boolean stateful) {
|
||||
LOGGER.info("loadMemroy : stateful=" + stateful);
|
||||
if (memoryRecoverUtil == null)
|
||||
memoryRecoverUtil = new MemoryRecoverUtil(engine.engine, engine.resources);
|
||||
memoryRecoverUtil.loadMemory(path, stateful);
|
||||
return "success";
|
||||
}
|
||||
|
||||
/*
|
||||
* 同步机制操作
|
||||
*/
|
||||
// 设置ContractRecord持久化的文件
|
||||
public void setCRFile(String fileName) {
|
||||
syncFileName = fileName.substring(15);
|
||||
File file = new File(syncDir + "/" + syncFileName);
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(fileName);
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setStartFlag(boolean b) {
|
||||
synchronized (startFlag) {
|
||||
if (startFlag == b && !b) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.startFlag = b;
|
||||
if (startFlag) { // start
|
||||
// 如果之前start过了,此次start就是一个检查点
|
||||
|
||||
filedTrans = new AtomicInteger(-1);
|
||||
syncRecords = new ArrayList<>();
|
||||
// dump current
|
||||
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd-HH_mm_ss");
|
||||
String path = format.format(new Date()) + "_" + new Random().nextInt();
|
||||
String state = dumpMemory(memoryDir + "/" + path);
|
||||
|
||||
syncRecords.add(new SyncRecord(SyncType.Memory, path));
|
||||
|
||||
changeCurrType(SyncType.Trans);
|
||||
path = format.format(new Date()) + "_" + new Random().nextInt();
|
||||
transRecordUtil.setFileName(path);
|
||||
syncRecords.add(new SyncRecord(SyncType.Trans, path));
|
||||
|
||||
// write syncRecords
|
||||
appendSyncFile(syncFileName, 0, 1);
|
||||
} else { // stop
|
||||
clearAllFiles();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void changeCurrType(SyncType t) {
|
||||
if (t == currType) return;
|
||||
|
||||
// finASyncRecord();
|
||||
currType = t;
|
||||
switch (currType) {
|
||||
case Trace:
|
||||
if (traceRecordUtil == null) {
|
||||
traceRecordUtil = new TraceRecordUtil(engine, this);
|
||||
}
|
||||
break;
|
||||
case Trans:
|
||||
if (transRecordUtil == null) {
|
||||
transRecordUtil = new TransRecordUtil(engine, this);
|
||||
}
|
||||
break;
|
||||
case Memory:
|
||||
if (memoryDumpUtil == null) memoryDumpUtil = new MemoryDumpUtil(engine.engine);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
// startASyncRecord();
|
||||
}
|
||||
|
||||
// 追加写sync文件
|
||||
public void appendSyncFile(String fileName, int start, int end) {
|
||||
File file = new File(syncDir + "/" + fileName);
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
for (int i = start; i <= end; i++) {
|
||||
pw.println(syncRecords.get(i).getContent());
|
||||
}
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Trans操作
|
||||
*/
|
||||
public synchronized String redo(String path) {
|
||||
if (transRecoverUtil == null) transRecoverUtil = new TransRecoverUtil(engine);
|
||||
|
||||
// 先清空,否则会重复执行一些trans
|
||||
if (transRecoverUtil.transRecords != null && !transRecoverUtil.transRecords.isEmpty())
|
||||
transRecoverUtil.transRecords.clear();
|
||||
|
||||
// 某一次检查点之后没有transRecords
|
||||
File file = new File(path);
|
||||
if (!file.exists()) return "success";
|
||||
|
||||
transRecoverUtil.setTraceRecords(path);
|
||||
transRecoverUtil.recoverFromTransRecord();
|
||||
return "success";
|
||||
}
|
||||
}
|
||||
21
src/main/java/org/bdware/sc/engine/TestClassFilter.java
Normal file
21
src/main/java/org/bdware/sc/engine/TestClassFilter.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
|
||||
import javax.script.ScriptEngine;
|
||||
|
||||
public class TestClassFilter {
|
||||
public TestClassFilter() {
|
||||
final String script = "print(java.lang.System.getProperty(\"java.home\"));" +
|
||||
"print(\"Create file variable\");" +
|
||||
"var File = Java.type(\"java.io.File\");";
|
||||
NashornScriptEngineFactory factory = new NashornScriptEngineFactory();
|
||||
ScriptEngine engine = factory.getScriptEngine(new YJSFilter());
|
||||
try {
|
||||
engine.eval(script);
|
||||
System.out.print("test push in");
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception caught:" + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
105
src/main/java/org/bdware/sc/engine/YJSClassLoader.java
Normal file
105
src/main/java/org/bdware/sc/engine/YJSClassLoader.java
Normal file
@@ -0,0 +1,105 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ClassFilter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class YJSClassLoader extends URLClassLoader {
|
||||
ClassFilter classFilter;
|
||||
File libDir = null;
|
||||
List<String> toLoad = new ArrayList<>();
|
||||
|
||||
public YJSClassLoader(ClassLoader parent, ClassFilter cf) {
|
||||
super(new URL[]{}, parent);
|
||||
classFilter = cf;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> findClass(final String fullName) throws ClassNotFoundException {
|
||||
if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
|
||||
throw new ClassNotFoundException(fullName);
|
||||
}
|
||||
return super.findClass(fullName);
|
||||
}
|
||||
|
||||
public Class<?> defineStubClass(String name, byte[] bytes) {
|
||||
return defineClass(name, bytes, 0, bytes.length);
|
||||
}
|
||||
|
||||
public void loadJar(InputStream inputStream, String path) {
|
||||
String fileName = unzipLibrary(inputStream, path);
|
||||
try {
|
||||
super.addURL(new File(fileName).toURI().toURL());
|
||||
} catch (MalformedURLException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] asByteArray(InputStream in) {
|
||||
try {
|
||||
ByteArrayOutputStream bo = new ByteArrayOutputStream();
|
||||
byte[] buff = new byte[1024];
|
||||
|
||||
for (int len = 0; (len = in.read(buff)) > 0; ) {
|
||||
bo.write(buff, 0, len);
|
||||
}
|
||||
return bo.toByteArray();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public String unzipLibrary(InputStream inputStream, String name) {
|
||||
try {
|
||||
if (libDir == null) {
|
||||
libDir = new File(System.getProperty("java.io.tmpdir"), "yjscontract_" + System.currentTimeMillis());
|
||||
libDir.mkdirs();
|
||||
}
|
||||
File f = new File(libDir, name);
|
||||
f.createNewFile();
|
||||
toLoad.add(f.getAbsolutePath());
|
||||
FileOutputStream fout = new FileOutputStream(f);
|
||||
byte[] buff = new byte[1024 * 100];
|
||||
for (int k = 0; (k = inputStream.read(buff)) > 0; ) {
|
||||
fout.write(buff, 0, k);
|
||||
}
|
||||
fout.close();
|
||||
return f.getAbsolutePath();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return "/dev/null";
|
||||
}
|
||||
|
||||
private void addDirToPath(String s) {
|
||||
try {
|
||||
System.out.println("[YJSClassloader] addtopath:" + s);
|
||||
Field field = ClassLoader.class.getDeclaredField("sys_paths");
|
||||
field.setAccessible(true);
|
||||
String[] path = (String[]) field.get(null);
|
||||
String[] temp = new String[path.length + 1];
|
||||
System.arraycopy(path, 0, temp, 0, path.length);
|
||||
temp[path.length] = s;
|
||||
field.set(null, temp);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void loadLibraries() {
|
||||
if (libDir != null)
|
||||
addDirToPath(libDir.getAbsolutePath());
|
||||
}
|
||||
|
||||
}
|
||||
11
src/main/java/org/bdware/sc/engine/YJSFilter.java
Normal file
11
src/main/java/org/bdware/sc/engine/YJSFilter.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.engine;
|
||||
|
||||
import wrp.jdk.nashorn.api.scripting.ClassFilter;
|
||||
|
||||
public class YJSFilter implements ClassFilter {
|
||||
@Override
|
||||
public boolean exposeToScripts(String arg0) {
|
||||
return true;
|
||||
//return arg0.compareTo("java.io.File") != 0;
|
||||
}
|
||||
}
|
||||
173
src/main/java/org/bdware/sc/engine/gbk.yjs
Normal file
173
src/main/java/org/bdware/sc/engine/gbk.yjs
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,34 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.ConfidentialContractUtil;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public class ConfidentialHandler implements AnnotationHook {
|
||||
private final FunctionNode fun;
|
||||
|
||||
public ConfidentialHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
ConfidentialContractUtil.copyTemplateToDestination(input);
|
||||
ScriptObjectMirror globalVars = (ScriptObjectMirror) desktopEngine.get("Global");
|
||||
ConfidentialContractUtil.dumpScriptAndStates(
|
||||
desktopEngine.engine, fun, input, globalVars);
|
||||
// run in SGX instead of Nashorn if function has @Confidential annotation
|
||||
ret = ConfidentialContractUtil.executeConfidentialContract(input);
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
86
src/main/java/org/bdware/sc/engine/hook/HomoVisitor.java
Normal file
86
src/main/java/org/bdware/sc/engine/hook/HomoVisitor.java
Normal file
@@ -0,0 +1,86 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.mockjava.JsonVisitor;
|
||||
import org.paillier.PaillierCipher;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
public class HomoVisitor extends JsonVisitor {
|
||||
public static RSAPublicKey publicKey;
|
||||
JsonElement root;
|
||||
public static RSAPrivateKey privateKey;
|
||||
|
||||
public HomoVisitor(JsonElement ret) {
|
||||
root = ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitObject(JsonObject homoConfig) {
|
||||
if (root.isJsonObject()) {
|
||||
JsonObject jo = root.getAsJsonObject();
|
||||
for (String key : homoConfig.keySet()) {
|
||||
if (jo.has(key)) {
|
||||
HomoVisitor visitor = new HomoVisitor(jo.get(key));
|
||||
visitor.visit(homoConfig.get(key));
|
||||
jo.add(key, visitor.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitJsonArray(JsonArray ele) {
|
||||
if (root.isJsonArray()) {
|
||||
JsonArray array = root.getAsJsonArray();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
HomoVisitor visitor = new HomoVisitor((array.get(i)));
|
||||
visitor.visit(ele.get(0));
|
||||
array.set(i, visitor.get());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonElement get() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitPrimitive(JsonPrimitive primitive) {
|
||||
if (primitive.isString()) {
|
||||
String method = primitive.getAsString();
|
||||
try {
|
||||
String result = "";
|
||||
if (method.equals("@encrypt")) {
|
||||
BigInteger i = handleRoot(root.getAsString());
|
||||
result = PaillierCipher.encrypt(i, publicKey);
|
||||
} else if (method.equals("@decrypt")) {
|
||||
BigInteger i = PaillierCipher.decrypt(root.getAsString(), privateKey);
|
||||
result = String.valueOf(i);
|
||||
} else {
|
||||
result = root.getAsString();
|
||||
}
|
||||
System.out.println(result);
|
||||
root = new JsonPrimitive(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
private BigInteger handleRoot(String data) {
|
||||
double d = Double.parseDouble(data);
|
||||
long l = (long) d;
|
||||
return BigInteger.valueOf(l);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.paillier.PaillierKeyPair;
|
||||
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
|
||||
public class HomomorphicDecryptHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
private final FunctionNode fun;
|
||||
|
||||
public HomomorphicDecryptHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
// GetHomArgs args =
|
||||
// new GetHomArgs(
|
||||
// input.getRequester(), this.fun.getSecretID().replaceAll("\"", ""));
|
||||
// String arg = JsonUtil.toJson(args);
|
||||
JsonElement homoDecryptConf = this.fun.getHomoDecryptConf();
|
||||
if (null != homoDecryptConf && !homoDecryptConf.isJsonNull()) {
|
||||
String res =
|
||||
JavaScriptEntry.executeContract(
|
||||
"keyManager_1",
|
||||
"getPrivKey",
|
||||
this.fun.getSecretID().replaceAll("\"", ""));
|
||||
LOGGER.info("HomomorphicDecryptHandler--------------------------------1: " + res);
|
||||
ContractResult results = JsonUtil.fromJson(res, ContractResult.class);
|
||||
String privKeyStr = results.result.getAsString();
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------2: " + privKeyStr);
|
||||
RSAPrivateKey privkey = (RSAPrivateKey) PaillierKeyPair.pemToPrivateKey(privKeyStr);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------3: " + privkey);
|
||||
HomoVisitor.privateKey = privkey;
|
||||
ret = getDecryptResult(homoDecryptConf, JsonUtil.parseObject(ret));
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
ret = new JsonObject();
|
||||
}
|
||||
return ret;
|
||||
// return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Object getDecryptResult(JsonElement homoDecryptConf, JsonElement data) {
|
||||
if (null == homoDecryptConf) {
|
||||
return data;
|
||||
}
|
||||
HomoVisitor visitor = new HomoVisitor(data);
|
||||
visitor.visit(homoDecryptConf);
|
||||
|
||||
JsonElement root = visitor.get();
|
||||
LOGGER.info("HomoRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.bdware.sc.node.FunctionNode;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import org.paillier.PaillierKeyPair;
|
||||
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
|
||||
public class HomomorphicEncryptHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
private final FunctionNode fun;
|
||||
|
||||
public HomomorphicEncryptHandler(FunctionNode fun) {
|
||||
this.fun = fun;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
try {
|
||||
LOGGER.info(
|
||||
"HomomorphicEncryptHandler--------------------------------1: "
|
||||
+ input.getRequester());
|
||||
LOGGER.info(
|
||||
"HomomorphicEncryptHandler--------------------------------2: "
|
||||
+ this.fun.getSecretID());
|
||||
JsonElement response = (JsonElement) ret;
|
||||
JsonElement homoEncryptConf = this.fun.getHomoEncryptConf();
|
||||
if (homoEncryptConf != null && !homoEncryptConf.isJsonNull()) {
|
||||
String res =
|
||||
JavaScriptEntry.executeContract(
|
||||
"keyManager_1",
|
||||
"getPubKey",
|
||||
this.fun.getSecretID().replaceAll("\"", ""));
|
||||
// String res =
|
||||
// JavaScriptEntry.executeContract(
|
||||
// this.fun.getKeyManagerID(),
|
||||
// "getPubKey",
|
||||
// this.fun.getSecretID().replaceAll("\"", ""));
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------4: " + res);
|
||||
ContractResult results = JsonUtil.fromJson(res, ContractResult.class);
|
||||
String pubKeyStr = results.result.getAsString();
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------5: " + pubKeyStr);
|
||||
HomoVisitor.publicKey = (RSAPublicKey) PaillierKeyPair.pemToPublicKey(pubKeyStr);
|
||||
// if (homoEncryptConf.getAsJsonPrimitive().isString())
|
||||
// homoEncryptConf = JsonParser.parseString(homoEncryptConf.getAsString());
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------6: " + homoEncryptConf);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------7: " + ret);
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------8: " + ret.toString());
|
||||
LOGGER.info("HomomorphicEncryptHandler--------------------------------9: " + JsonUtil.toJson(ret));
|
||||
ret = getEncryptResult(homoEncryptConf, response);
|
||||
if (ret != null) {
|
||||
return ret;
|
||||
}
|
||||
ret = new JsonObject();
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private Object getEncryptResult(JsonElement homoEncryptConf, JsonElement data) {
|
||||
// if (null == homoEncryptConf || homoEncryptConf.getAsString().isEmpty()) {
|
||||
// return data;
|
||||
// }
|
||||
if (null == homoEncryptConf) {
|
||||
return data;
|
||||
}
|
||||
HomoVisitor visitor = new HomoVisitor(data);
|
||||
visitor.visit(homoEncryptConf);
|
||||
|
||||
JsonElement root = visitor.get();
|
||||
System.out.println("HomoRetInvoke: " + root);
|
||||
LOGGER.info("HomoRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
59
src/main/java/org/bdware/sc/engine/hook/MaskHandler.java
Normal file
59
src/main/java/org/bdware/sc/engine/hook/MaskHandler.java
Normal file
@@ -0,0 +1,59 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonParser;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
|
||||
public class MaskHandler implements AnnotationHook {
|
||||
private static final Logger LOGGER = LogManager.getLogger(MaskHandler.class);
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine Engine, Object ret) {
|
||||
try {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) Engine;
|
||||
ProjectConfig projectConfig = desktopEngine.getProjectConfig();
|
||||
JsonElement maskConf = projectConfig.getMask(input.getAction());
|
||||
LOGGER.info("execute maskConf: " + maskConf);
|
||||
if (null != maskConf) {
|
||||
String s1 = ret.toString();
|
||||
//budeijin
|
||||
//"{\"count\":1}"
|
||||
//{"count":1}
|
||||
//System.out.println(s1);
|
||||
s1 = s1.replace("\\", "");
|
||||
s1 = s1.substring(1, s1.length() - 1);
|
||||
//System.out.println(s1);
|
||||
//System.out.println(JsonParser.parseString(s1));
|
||||
MaskVisitor visitor = new MaskVisitor(JsonParser.parseString(s1));
|
||||
visitor.visit(maskConf);
|
||||
ret = visitor.get();
|
||||
System.out.println(maskConf);
|
||||
if (null != ret) {
|
||||
return ret;
|
||||
}
|
||||
ret = JsonParser.parseString("");
|
||||
}
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
public Object getMaskResult(JsonElement maskConfigInvoke, JsonElement data) {
|
||||
if (null == maskConfigInvoke || maskConfigInvoke.getAsString().isEmpty()) {
|
||||
return data;
|
||||
}
|
||||
MaskVisitor visitor = new MaskVisitor(data);
|
||||
visitor.visit(maskConfigInvoke);
|
||||
JsonElement root = visitor.get();
|
||||
LOGGER.info("MaskRetInvoke: " + root);
|
||||
return root;
|
||||
}
|
||||
}
|
||||
97
src/main/java/org/bdware/sc/engine/hook/MaskVisitor.java
Normal file
97
src/main/java/org/bdware/sc/engine/hook/MaskVisitor.java
Normal file
@@ -0,0 +1,97 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.cryptology.AESEncryptionImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.cryptology.FormatPreservingEncryptionImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.differentialPrivacy.EpsilonDifferentialPrivacyImpl;
|
||||
import com.alibaba.datax.transport.transformer.maskingMethods.irreversibleInterference.MD5EncryptionImpl;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.mockjava.JsonVisitor;
|
||||
|
||||
public class MaskVisitor extends JsonVisitor {
|
||||
JsonElement root;
|
||||
|
||||
public MaskVisitor(JsonElement ret) {
|
||||
root = ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitObject(JsonObject mask) {
|
||||
if (root.isJsonObject()) {
|
||||
JsonObject jo = root.getAsJsonObject();
|
||||
for (String key : mask.keySet()) {
|
||||
if (jo.has(key)) {
|
||||
//TODO
|
||||
MaskVisitor visitor = new MaskVisitor(jo.get(key));
|
||||
visitor.visit(mask.get(key));
|
||||
jo.add(key, visitor.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JsonVisitor visitJsonArray(JsonArray ele) {
|
||||
if (root.isJsonArray()) {
|
||||
JsonArray array = root.getAsJsonArray();
|
||||
for (int i = 0; i < array.size(); i++) {
|
||||
MaskVisitor visitor = new MaskVisitor(array.get(i));
|
||||
visitor.visit(ele.get(0));
|
||||
array.set(i, visitor.get());
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JsonElement get() {
|
||||
return root;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
public JsonVisitor visitPrimitive(JsonPrimitive primitive) {
|
||||
//
|
||||
if (primitive.isString()) {
|
||||
String method = primitive.getAsString();
|
||||
try {
|
||||
String result = "";
|
||||
//md5不需要参数
|
||||
if (method.equals("md5")) {
|
||||
MD5EncryptionImpl masker = new MD5EncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
} else if (method.equals("aes")) {
|
||||
AESEncryptionImpl masker = new AESEncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
} else if (method.equals("fpe")) {
|
||||
FormatPreservingEncryptionImpl masker = new FormatPreservingEncryptionImpl();
|
||||
result = masker.execute(root.getAsString());
|
||||
}
|
||||
//edp需要精度的参数
|
||||
else if (method.equals("edp")) {
|
||||
EpsilonDifferentialPrivacyImpl masker = new EpsilonDifferentialPrivacyImpl();
|
||||
double epsilon = 1;
|
||||
|
||||
result = "" + masker.maskOne(root.getAsDouble(), epsilon);
|
||||
} else {
|
||||
result = root.getAsString();
|
||||
}
|
||||
System.out.println(result);
|
||||
root = new JsonPrimitive(result);
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//String result = masker.execute(primitive.toString());
|
||||
//System.out.println(result);
|
||||
|
||||
//root = new JsonPrimitive(root.getAsString().substring(0, 2));
|
||||
//https://github.com/guohf/DataX-Masking
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.mockjava.MockUtil;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.bean.ProjectConfig;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
|
||||
public class MockTemplateHandler implements AnnotationHook {
|
||||
@Override
|
||||
public Object handle(ContractRequest request, JSEngine engine, Object ret) {
|
||||
if (request.fromDebug()) {
|
||||
System.out.println(request.getAction());
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
ProjectConfig projectConfig = desktopEngine.getProjectConfig();
|
||||
String template = projectConfig.getMock(request.getAction());
|
||||
if (template != null && template.length() > 0) {
|
||||
System.out.println(template);
|
||||
MockUtil Mock = new MockUtil();
|
||||
return Mock.mock(template).toString();
|
||||
}
|
||||
else return ret; //When mock config is null defined just ignore.
|
||||
} else return ret;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonNull;
|
||||
import com.google.gson.JsonPrimitive;
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.JSONTool;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public class ObjToJsonHandler implements AnnotationHook {
|
||||
// private static final Logger LOGGER = LogManager.getLogger(ObjToJsonHandler.class);
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine desktopEngine, Object ret) {
|
||||
JsonElement je;
|
||||
if (ret == null) {
|
||||
je = JsonNull.INSTANCE;
|
||||
} else if (ret instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror ret2 = (ScriptObjectMirror) ret;
|
||||
// LOGGER.debug("[before parse to json]" + ret2);
|
||||
je = JSONTool.copy(ret2);
|
||||
} else if (ret instanceof jdk.nashorn.api.scripting.ScriptObjectMirror) {
|
||||
jdk.nashorn.api.scripting.ScriptObjectMirror ret2 =
|
||||
(jdk.nashorn.api.scripting.ScriptObjectMirror) ret;
|
||||
// LOGGER.debug("[before parse to json]" + ret2);
|
||||
je = JSONTool.copy(ret2);
|
||||
} else if (ret instanceof Number) {
|
||||
je = new JsonPrimitive((Number) ret);
|
||||
} else if (ret instanceof Character) {
|
||||
je = new JsonPrimitive((Character) ret);
|
||||
} else if (ret instanceof Boolean) {
|
||||
je = new JsonPrimitive((Boolean) ret);
|
||||
} else if (ret instanceof String) {
|
||||
je = new JsonPrimitive((String) ret);
|
||||
} else {
|
||||
je = new JsonPrimitive(ret.toString());
|
||||
}
|
||||
return je;
|
||||
}
|
||||
}
|
||||
67
src/main/java/org/bdware/sc/engine/hook/ReadMeHandler.java
Normal file
67
src/main/java/org/bdware/sc/engine/hook/ReadMeHandler.java
Normal file
@@ -0,0 +1,67 @@
|
||||
package org.bdware.sc.engine.hook;
|
||||
|
||||
import org.bdware.sc.JSEngine;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.node.AnnotationHook;
|
||||
import org.commonmark.node.FencedCodeBlock;
|
||||
import org.commonmark.node.Heading;
|
||||
import org.commonmark.node.Node;
|
||||
import org.commonmark.node.Text;
|
||||
import org.commonmark.parser.Parser;
|
||||
|
||||
public class ReadMeHandler implements AnnotationHook {
|
||||
String getReadMeData(DesktopEngine desktopEngine, ContractRequest c) {
|
||||
String fileReadme =
|
||||
desktopEngine
|
||||
.getResources()
|
||||
.loadAsString("/assets/README.md"); // is "/README.md" not"./README.md"!!!!
|
||||
// System.out.println("fileReadme:" + fileReadme);
|
||||
if (null == fileReadme) {
|
||||
return "项目目录下无预览文档";
|
||||
} else {
|
||||
String result = "未能返回调试调用结果";
|
||||
String targetFunction = c.getAction();
|
||||
try {
|
||||
Parser parser = Parser.builder().build();
|
||||
Node document = parser.parse(fileReadme);
|
||||
Node visitor = document.getFirstChild();
|
||||
while (visitor != null) {
|
||||
if (visitor instanceof Heading) {
|
||||
if (((Heading) visitor).getLevel() == 2) {
|
||||
if (((Text) (visitor.getFirstChild()))
|
||||
.getLiteral()
|
||||
.equals(targetFunction)) {
|
||||
FencedCodeBlock blockResult =
|
||||
(FencedCodeBlock)
|
||||
(visitor.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext()
|
||||
.getNext());
|
||||
result = blockResult.getLiteral();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
visitor = visitor.getNext();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object handle(ContractRequest input, JSEngine engine, Object ret) {
|
||||
DesktopEngine desktopEngine = (DesktopEngine) engine;
|
||||
if (input.fromDebug() && (ret == null || ret.equals("emptyMock"))) {
|
||||
ret = getReadMeData(desktopEngine, input);
|
||||
System.out.println(ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/engine/setArgs/GetHomArgs.java
Normal file
12
src/main/java/org/bdware/sc/engine/setArgs/GetHomArgs.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.engine.setArgs;
|
||||
|
||||
public class GetHomArgs {
|
||||
public String secretID;
|
||||
|
||||
public GetHomArgs() {
|
||||
}
|
||||
|
||||
public GetHomArgs(String secretID) {
|
||||
this.secretID = secretID;
|
||||
}
|
||||
}
|
||||
298
src/main/java/org/bdware/sc/handler/ContractHandler.java
Normal file
298
src/main/java/org/bdware/sc/handler/ContractHandler.java
Normal file
@@ -0,0 +1,298 @@
|
||||
package org.bdware.sc.handler;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import org.bdware.sc.bean.Contract;
|
||||
import org.bdware.sc.conn.Description;
|
||||
import org.bdware.sc.conn.MsgHandler;
|
||||
import org.bdware.sc.conn.ResultCallback;
|
||||
import org.bdware.sc.conn.ServiceServer;
|
||||
import org.bdware.sc.get.GetMessage;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class ContractHandler extends MsgHandler implements Runnable {
|
||||
private static final Logger LOGGER = LogManager.getLogger(ContractHandler.class);
|
||||
ContractProcess cs;
|
||||
String identifier = "null";
|
||||
|
||||
public ContractHandler(ContractProcess cs) {
|
||||
this.cs = cs;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
System.out.println("ContractHandler: exit in 2 seconds!");
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@Description("start sync mech")
|
||||
public void startSync(GetMessage msg, ResultCallback cb) {
|
||||
cs.startSync();
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("stop sync mech")
|
||||
public void stopSync(GetMessage msg, ResultCallback cb) {
|
||||
cs.stopSync();
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("set ContractRecord file name")
|
||||
public void setCRFile(GetMessage msg, ResultCallback cb) {
|
||||
cs.setCRFile(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("set contractDir")
|
||||
public void setDir(GetMessage msg, ResultCallback cb) {
|
||||
System.out.println("ContractHandler setDir");
|
||||
cs.setDir(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getDebug")
|
||||
public void getDebug(GetMessage msg, ResultCallback cb) {
|
||||
LOGGER.debug("getDebug");
|
||||
cb.onResult(JsonUtil.toJson(cs.isDebug()));
|
||||
}
|
||||
|
||||
@Description("clearSyncFiles")
|
||||
public void clearSyncFiles(GetMessage msg, ResultCallback cb) {
|
||||
cs.clearSyncFiles(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("changeDumpPeriod")
|
||||
public void changeDumpPeriod(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.changeDumpPeriod(msg.arg));
|
||||
}
|
||||
|
||||
@Description("getDumpPeriod")
|
||||
public void getDumpPeriod(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDumpPeriod());
|
||||
}
|
||||
|
||||
@Description("getCachedTransRecords")
|
||||
public void getCachedTransRecords(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getCachedTransRecords(msg.arg));
|
||||
}
|
||||
|
||||
@Description("start auto dump")
|
||||
public void startAutoDump(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.startAutoDump());
|
||||
}
|
||||
|
||||
@Description("register manager port")
|
||||
public void registerMangerPort(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.registerMangerPort(msg.arg));
|
||||
}
|
||||
|
||||
@Description("set current ContractBundle")
|
||||
public void setContractBundle(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setContractBundle(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("get current contract name")
|
||||
public void getContractName(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getContractName());
|
||||
}
|
||||
|
||||
@Description("set current Contract")
|
||||
public void setContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setContract(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description(value = "execute contract")
|
||||
public void executeContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.executeContract(msg.arg));
|
||||
}
|
||||
|
||||
@Description("set DesktopPermission")
|
||||
public void setDesktopPermission(GetMessage msg, ResultCallback cb) {
|
||||
String result = cs.setDesktopPermission(msg.arg);
|
||||
cb.onResult(result);
|
||||
}
|
||||
|
||||
@Description("change debug Flag")
|
||||
public void changeDebugFlag(GetMessage msg, ResultCallback cb) {
|
||||
String result = cs.changeDebugFlag(Boolean.valueOf(msg.arg));
|
||||
cb.onResult(result);
|
||||
}
|
||||
|
||||
@Description("get functionEvaluates ")
|
||||
public void functionEvaluates(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.evaluatesAnalysis(msg.arg));
|
||||
}
|
||||
|
||||
@Description("get memory set")
|
||||
public void getMemorySet(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getMemorySet());
|
||||
}
|
||||
|
||||
@Description("get logType ")
|
||||
public void getLogType(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getLogType(msg.arg));
|
||||
}
|
||||
|
||||
@Description("exit Contract!")
|
||||
public void suicide(GetMessage msg, ResultCallback cb) {
|
||||
Map<String, Object> ret = new HashMap<>();
|
||||
ret.put("status", "success");
|
||||
cs.beforeSuicide();
|
||||
if (cs.checkSub()) {
|
||||
ret.put("cleanSub", true);
|
||||
}
|
||||
ServiceServer.executor.execute(this);
|
||||
cb.onResult(JsonUtil.toJson(ret));
|
||||
}
|
||||
|
||||
@Description("check alive")
|
||||
public void ping(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult("pong");
|
||||
}
|
||||
|
||||
@Description("dump contract process memory")
|
||||
public void getMemoryDump(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getMemoryDump(msg.arg));
|
||||
}
|
||||
|
||||
@Description("get memory usage")
|
||||
public void getStorage(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getStorage());
|
||||
}
|
||||
|
||||
@Description("redo by local trans record")
|
||||
public void redo(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.redo(msg.arg));
|
||||
}
|
||||
|
||||
@Description("load dumped memory")
|
||||
public void loadMemory(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.loadMemoryDump(msg.arg));
|
||||
}
|
||||
|
||||
@Description("setDBInfo, the db is used to store local logs")
|
||||
public void setDBInfo(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.setDBInfo(msg.arg));
|
||||
}
|
||||
|
||||
@Description("getUsedMemory")
|
||||
public void getUsedMemory(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getUsedMemory("") + "");
|
||||
}
|
||||
|
||||
@Description("showPermission")
|
||||
public void showPermission(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.showPermission());
|
||||
}
|
||||
|
||||
@Description("is signature required?")
|
||||
public void isSigRequired(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.isSigRequired() + "");
|
||||
}
|
||||
|
||||
@Description("Get Declared Events")
|
||||
public void getDeclaredEvents(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDeclaredEvents());
|
||||
}
|
||||
|
||||
@Description("Get Contract Annotations")
|
||||
public void getAnnotations(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getAnnotations());
|
||||
}
|
||||
|
||||
@Description("Get Exported Functions")
|
||||
public void getExportedFunctions(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getExportedFunctions());
|
||||
}
|
||||
|
||||
@Description("Whether current process is contract process, always cmi")
|
||||
public void isContractProcess(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.cmi);
|
||||
}
|
||||
|
||||
@Description("get contract")
|
||||
public void getContract(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getContract());
|
||||
}
|
||||
|
||||
@Description("setPID")
|
||||
public void setPID(GetMessage msg, ResultCallback cb) {
|
||||
cs.setPID(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("setProjectConfig")
|
||||
public void setProjectConfig(GetMessage msg, ResultCallback cb) {
|
||||
LOGGER.debug("ContractHandler: " + msg.arg);
|
||||
cs.setProjectConfig(msg.arg);
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getPID")
|
||||
public void getPID(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getPID());
|
||||
}
|
||||
|
||||
@Description("requestLogSize")
|
||||
public void getLogSize(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.logSize() + "");
|
||||
}
|
||||
|
||||
@Description("request Log")
|
||||
public void requestLog(GetMessage msg, ResultCallback cb) {
|
||||
String[] data = msg.arg.split(",");
|
||||
cb.onResult(cs.requestLog(Long.parseLong(data[0]), Integer.parseInt(data[1])));
|
||||
}
|
||||
|
||||
@Description("request LastLog")
|
||||
public void requestLastLog(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.requestLast(Integer.parseInt(msg.arg)));
|
||||
}
|
||||
|
||||
@Description("setIdentifier")
|
||||
public void setIdentifier(GetMessage msg, ResultCallback cb) {
|
||||
identifier = msg.arg;
|
||||
cb.onResult("success");
|
||||
}
|
||||
|
||||
@Description("getIdentifier")
|
||||
public void getIdentifier(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(identifier);
|
||||
}
|
||||
|
||||
@Description("getControlFlow")
|
||||
public void getControlFlow(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getControlFlow(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("getStateful")
|
||||
public void getStateful(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getStateful());
|
||||
}
|
||||
|
||||
@Description("parseYpkPermissions")
|
||||
public void parseYpkPermissions(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.parseYpkPermissions(msg.arg));
|
||||
}
|
||||
|
||||
@Description("staticVerify")
|
||||
public void staticVerify(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.staticVerify(JsonUtil.fromJson(msg.arg, Contract.class)));
|
||||
}
|
||||
|
||||
@Description("getDependentContracts")
|
||||
public void getDependentContracts(GetMessage msg, ResultCallback cb) {
|
||||
cb.onResult(cs.getDependentContracts());
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
13
src/main/java/org/bdware/sc/handler/Exitor.java
Normal file
13
src/main/java/org/bdware/sc/handler/Exitor.java
Normal file
@@ -0,0 +1,13 @@
|
||||
package org.bdware.sc.handler;
|
||||
|
||||
public class Exitor implements Runnable {
|
||||
public void run() {
|
||||
System.out.println("ContractHandler: exit in 2 seconds!");
|
||||
try {
|
||||
Thread.sleep(2000);
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
21
src/main/java/org/bdware/sc/memory/JSEDump.java
Normal file
21
src/main/java/org/bdware/sc/memory/JSEDump.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSEDump implements Serializable {
|
||||
long invokeID;
|
||||
long ranSeed;
|
||||
int numsOfCopies;
|
||||
|
||||
public JSEDump(long id,long ra,int nums){
|
||||
invokeID = id;
|
||||
ranSeed = ra;
|
||||
numsOfCopies = nums;
|
||||
}
|
||||
|
||||
public void printContent(){
|
||||
System.out.println("invokeID=" + invokeID);
|
||||
System.out.println("ranSeed=" + ranSeed);
|
||||
System.out.println("numsOfCopies=" + numsOfCopies);
|
||||
}
|
||||
}
|
||||
40
src/main/java/org/bdware/sc/memory/MOType.java
Normal file
40
src/main/java/org/bdware/sc/memory/MOType.java
Normal file
@@ -0,0 +1,40 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import jdk.internal.dynalink.beans.StaticClass;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
public enum MOType {
|
||||
String(true), Int(true), Double(true), Boolean(true),JSObject(false), JSArray(false), JavaObject(false), Method(false),
|
||||
Undefined(true), JSFunction(false),JSStatic(false);
|
||||
|
||||
private boolean isPrimitive;
|
||||
|
||||
MOType(boolean isPrimitive) {
|
||||
this.isPrimitive = (isPrimitive);
|
||||
}
|
||||
|
||||
public static MOType getType(Object obj) {
|
||||
if (obj == null)
|
||||
return Undefined;
|
||||
if (obj instanceof Integer) {
|
||||
return Int;
|
||||
} else if (obj instanceof Double) {
|
||||
return Double;
|
||||
} else if (obj instanceof String) {
|
||||
return String;
|
||||
} else if (obj instanceof ScriptObjectMirror) {
|
||||
// ------
|
||||
return JSObject;
|
||||
}else if(obj instanceof StaticClass) {
|
||||
return JSStatic;
|
||||
}else if(obj instanceof Boolean){
|
||||
return Boolean;
|
||||
}
|
||||
return JSObject;
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return isPrimitive;
|
||||
}
|
||||
|
||||
}
|
||||
12
src/main/java/org/bdware/sc/memory/MemoryArrayObject.java
Normal file
12
src/main/java/org/bdware/sc/memory/MemoryArrayObject.java
Normal file
@@ -0,0 +1,12 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
public class MemoryArrayObject extends MemoryJSObject{
|
||||
|
||||
private static final long serialVersionUID = -5805776423219733634L;
|
||||
|
||||
public MemoryArrayObject(long id) {
|
||||
super(id);
|
||||
type = MOType.JSArray;
|
||||
}
|
||||
|
||||
}
|
||||
231
src/main/java/org/bdware/sc/memory/MemoryDump.java
Normal file
231
src/main/java/org/bdware/sc/memory/MemoryDump.java
Normal file
@@ -0,0 +1,231 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
|
||||
public class MemoryDump implements Serializable {
|
||||
transient long id;
|
||||
transient Map<Object, Long> allocated; //js对象,id
|
||||
|
||||
Map<Long, MemoryObject> objects; //id,memory对象
|
||||
JSEDump jseDump;
|
||||
|
||||
transient Map<Long, Object> recreate;
|
||||
|
||||
public MemoryDump() {
|
||||
objects = new HashMap<>();
|
||||
allocated = new HashMap<>();
|
||||
id = 0;
|
||||
getRoot();
|
||||
}
|
||||
|
||||
public static MemoryDump loadFromStr(String memDump) {
|
||||
JsonElement jo = new com.google.gson.JsonParser().parse(memDump);
|
||||
// JsonElement objs = jo.getAsJsonObject().get("objects");
|
||||
// JsonObject map = objs.getAsJsonObject();
|
||||
JsonObject map = jo.getAsJsonObject();
|
||||
MemoryDump ret = new MemoryDump();
|
||||
for (Entry<String, JsonElement> entry : map.entrySet()) {
|
||||
long id = Long.parseLong(entry.getKey());
|
||||
JsonObject obj = entry.getValue().getAsJsonObject();
|
||||
MOType type = MOType.valueOf(obj.get("type").getAsString());
|
||||
MemoryObject mo = null;
|
||||
|
||||
switch (type) {
|
||||
case JSObject:
|
||||
case JSArray:
|
||||
mo = JsonUtil.fromJson(obj, MemoryJSObject.class);
|
||||
break;
|
||||
case JSFunction:
|
||||
mo = JsonUtil.fromJson(obj, MemoryFunctionObject.class);
|
||||
break;
|
||||
case Int:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
mo.data = Integer.parseInt(obj.get("data").getAsString());
|
||||
break;
|
||||
case Boolean:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
mo.data = Boolean.parseBoolean(obj.get("data").getAsString());
|
||||
break;
|
||||
case String:
|
||||
case Double:
|
||||
mo = JsonUtil.fromJson(obj, MemoryObject.class);
|
||||
break;
|
||||
default:
|
||||
System.out.println("[MemoryDump] todo, missing type:" + type.toString());
|
||||
break;
|
||||
}
|
||||
ret.objects.put(id, mo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public Map<Long, MemoryObject> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public void setObjects(Map<Long, MemoryObject> m) {
|
||||
this.objects = m;
|
||||
}
|
||||
|
||||
public MemoryJSObject getRoot() {
|
||||
if (objects.containsKey(0L))
|
||||
return (MemoryJSObject) objects.get(0L);
|
||||
else {
|
||||
MemoryJSObject jo = new MemoryJSObject(0);
|
||||
objects.put((long) 0, jo);
|
||||
return jo;
|
||||
}
|
||||
}
|
||||
|
||||
public long allocate(Object obj) {
|
||||
if (obj == null)
|
||||
return -1;
|
||||
|
||||
long currID;
|
||||
|
||||
id++;
|
||||
currID = id;
|
||||
if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
/*
|
||||
String obj2 = "jdk.internal.dynalink.beans.StaticClass.class";
|
||||
if (allocated.containsKey(obj2))
|
||||
return allocated.get(obj2);
|
||||
allocated.put(obj2, currID);
|
||||
*/
|
||||
} else {
|
||||
if (allocated.containsKey(obj))
|
||||
return allocated.get(obj);
|
||||
allocated.put(obj, currID);
|
||||
}
|
||||
|
||||
|
||||
// 如果是对象
|
||||
if (obj.getClass() == ScriptObjectMirror.class) {
|
||||
ScriptObjectMirror som = (ScriptObjectMirror) obj;
|
||||
if (som.isFunction()) {
|
||||
MemoryFunctionObject fo = new MemoryFunctionObject(currID);
|
||||
objects.put(currID, fo);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
fo.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
} else if (som.isArray()) {
|
||||
MemoryArrayObject ao = new MemoryArrayObject(currID);
|
||||
objects.put(currID, ao);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
ao.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
} else {
|
||||
MemoryJSObject jo = new MemoryJSObject(currID);
|
||||
objects.put(currID, jo);
|
||||
for (String str : som.getOwnKeys(true)) {
|
||||
jo.addField(str, allocate(som.getMember(str)));
|
||||
}
|
||||
}
|
||||
} else if (obj.getClass() == wrp.jdk.nashorn.internal.runtime.Undefined.class) {
|
||||
|
||||
} else if (obj.getClass() == jdk.internal.dynalink.beans.StaticClass.class) {
|
||||
//regard as String
|
||||
|
||||
// MemoryObject mo = new MemoryObject(currID);
|
||||
// mo.type = MOType.String;
|
||||
// mo.data = "jdk.internal.dynalink.beans.StaticClass";
|
||||
// objects.put(currID, mo);
|
||||
} else {
|
||||
MOType type = MOType.getType(obj);
|
||||
if (type.isPrimitive()) {
|
||||
MemoryObject mo = new MemoryObject(currID);
|
||||
mo.type = type;
|
||||
mo.data = obj;
|
||||
objects.put(currID, mo);
|
||||
} else
|
||||
System.out.println("[MemoryDump] Allocat MetType:" + obj.getClass() + " now id=" + currID);
|
||||
|
||||
}
|
||||
return currID;
|
||||
}
|
||||
|
||||
public Map<Long, Object> recreateObject() {
|
||||
recreate = new HashMap<>();
|
||||
fillRecreate();
|
||||
fillJO();
|
||||
return recreate;
|
||||
}
|
||||
|
||||
private void fillJO() {
|
||||
for (Long key : objects.keySet()) {
|
||||
MemoryObject mo = objects.get(key);
|
||||
if (mo == null)
|
||||
continue;
|
||||
|
||||
switch (mo.type) {
|
||||
case JSObject:
|
||||
case JSArray:
|
||||
MemoryJSObject mjo = (MemoryJSObject) mo;
|
||||
ScriptObjectMirror jo = (ScriptObjectMirror) recreate.get(key);
|
||||
for (String field : mjo.fields.keySet()) {
|
||||
Object temp = recreate.get(mjo.fields.get(field));
|
||||
|
||||
if (mjo.fields.get(field) >= 0) {
|
||||
if (field.length() > 0)
|
||||
jo.setMember(field, temp);
|
||||
else
|
||||
jo.setMember(" ", temp);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void fillRecreate() {
|
||||
Context.setGlobal(JavaScriptEntry.getEngineGlobal());
|
||||
for (Long key : objects.keySet()) {
|
||||
Object obj = null;
|
||||
MemoryObject mo = objects.get(key);
|
||||
if (mo == null) {
|
||||
continue;
|
||||
}
|
||||
switch (mo.type) {
|
||||
case JSArray:
|
||||
obj = ScriptObjectMirror.wrap(Global.allocate(new int[0]), JavaScriptEntry.getEngineGlobal());
|
||||
break;
|
||||
case JSObject:
|
||||
obj = ScriptObjectMirror.wrap(new JO(PropertyMap.newMap()), JavaScriptEntry.getEngineGlobal());
|
||||
break;
|
||||
case JSFunction:
|
||||
break;
|
||||
case String:
|
||||
case Int:
|
||||
obj = mo.data;
|
||||
break;
|
||||
case Double:
|
||||
obj = Double.parseDouble(mo.data.toString());
|
||||
break;
|
||||
default:
|
||||
System.out.println("[MemoryDump] todo, missing type:" + mo.type.toString());
|
||||
break;
|
||||
}
|
||||
|
||||
recreate.put(key, obj);
|
||||
}
|
||||
}
|
||||
}
|
||||
155
src/main/java/org/bdware/sc/memory/MemoryDumpUtil.java
Normal file
155
src/main/java/org/bdware/sc/memory/MemoryDumpUtil.java
Normal file
@@ -0,0 +1,155 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import java.io.*;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
public class MemoryDumpUtil {
|
||||
public static final String STATELESS_MEMORY = "statelessContractMemory";
|
||||
public static AtomicInteger checkPointCounter; //用于common模式下的检查点计数
|
||||
NashornScriptEngine engine;
|
||||
String dumpContent;
|
||||
MemoryDump memoryDump = null;
|
||||
|
||||
public MemoryDumpUtil(NashornScriptEngine en) {
|
||||
this.engine = en;
|
||||
}
|
||||
|
||||
public static String getContentFromFile(String path) {
|
||||
File file = new File(path);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
reader = new ObjectInputStream(gzin);
|
||||
MemoryDump memoryDump = new MemoryDump();
|
||||
//memoryDump.objects = (Map<Long, MemoryObject>) reader.readObject();
|
||||
memoryDump = (MemoryDump) reader.readObject();
|
||||
reader.close();
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
ret += ("<seperate>" + memoryDump.jseDump.invokeID + ";" + memoryDump.jseDump.ranSeed + ";" + memoryDump.jseDump.numsOfCopies + "");
|
||||
return ret;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
public static String getContentFromFile2(String path) {
|
||||
File file = new File(path);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
reader = new ObjectInputStream(fileout);
|
||||
String ret = (String)reader.readObject();
|
||||
reader.close();
|
||||
return ret;
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
*/
|
||||
|
||||
//stateful 表示合约是有/无状态合约
|
||||
public String dumpMemory(String path, boolean stateful) {
|
||||
synchronized (engine) {
|
||||
String ret;
|
||||
memoryDump = new MemoryDump();
|
||||
|
||||
if (stateful) {
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
for (String key : bindings.keySet()) {
|
||||
Object obj = bindings.get(key);
|
||||
long id = memoryDump.allocate(obj);
|
||||
root.addField(key, id);
|
||||
}
|
||||
memoryDump.jseDump = new JSEDump(JavaScriptEntry.invokeID, Long.parseLong(JavaScriptEntry.currentSyncUtil.contractID), JavaScriptEntry.numOfCopies);
|
||||
ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
} else { //无状态合约
|
||||
memoryDump.jseDump = new JSEDump(JavaScriptEntry.invokeID, Long.parseLong(JavaScriptEntry.currentSyncUtil.contractID), JavaScriptEntry.numOfCopies);
|
||||
memoryDump.objects.clear();
|
||||
ret = JsonUtil.toPrettyJson(memoryDump.objects);
|
||||
}
|
||||
|
||||
ret += "--seperate--";
|
||||
ret += (memoryDump.jseDump.invokeID + ";" + memoryDump.jseDump.ranSeed + ";" + memoryDump.jseDump.numsOfCopies);
|
||||
|
||||
if (path == null || path.equals("")) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File mem = new File(path);
|
||||
File parent = mem.getParentFile();
|
||||
if (!parent.exists()) parent.mkdirs();
|
||||
ObjectOutputStream writer;
|
||||
try {
|
||||
FileOutputStream fileout = new FileOutputStream(mem);
|
||||
GZIPOutputStream out = new GZIPOutputStream(fileout);
|
||||
writer = new ObjectOutputStream(out);
|
||||
//writer.writeObject(memoryDump.objects);
|
||||
writer.writeObject(memoryDump);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
memoryDump = null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public String dumpMemory(String path) {
|
||||
memoryDump = new MemoryDump();
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
System.out.println("[MemoryDumpUtil] bindings size=" + bindings.size());
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
for (String key : bindings.keySet()) {
|
||||
System.out.println("[MemoryDumpUtil] dumpMemory " + key);
|
||||
Object obj = bindings.get(key);
|
||||
long id = memoryDump.allocate(obj);
|
||||
root.addField(key, id);
|
||||
|
||||
System.out.println("[root addFiled] key=" + key + " id=" + id);
|
||||
}
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump);
|
||||
dumpContent = ret;
|
||||
|
||||
if(path == null || path.equals("")) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
File mem = new File(path);
|
||||
File parent = mem.getParentFile();
|
||||
if (!parent.exists())
|
||||
parent.mkdirs();
|
||||
ObjectOutputStream writer;
|
||||
try {
|
||||
FileOutputStream fileout = new FileOutputStream(mem);
|
||||
writer = new ObjectOutputStream(fileout);
|
||||
writer.writeObject(dumpContent);
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
memoryDump = null;
|
||||
return ret;
|
||||
}
|
||||
*/
|
||||
}
|
||||
19
src/main/java/org/bdware/sc/memory/MemoryFunctionObject.java
Normal file
19
src/main/java/org/bdware/sc/memory/MemoryFunctionObject.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemoryFunctionObject extends MemoryObject {
|
||||
private static final long serialVersionUID = 5169037078273981613L;
|
||||
Map<String, Long> fields;
|
||||
|
||||
public MemoryFunctionObject(long id) {
|
||||
super(id);
|
||||
fields = new HashMap<>();
|
||||
type = MOType.JSFunction;
|
||||
}
|
||||
|
||||
public void addField(String key, long id) {
|
||||
fields.put(key, id);
|
||||
}
|
||||
}
|
||||
19
src/main/java/org/bdware/sc/memory/MemoryJSObject.java
Normal file
19
src/main/java/org/bdware/sc/memory/MemoryJSObject.java
Normal file
@@ -0,0 +1,19 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class MemoryJSObject extends MemoryObject {
|
||||
private static final long serialVersionUID = -2290414347562477503L;
|
||||
LinkedHashMap<String, Long> fields;
|
||||
|
||||
public MemoryJSObject(long id) {
|
||||
super(id);
|
||||
fields = new LinkedHashMap<>();
|
||||
type = MOType.JSObject;
|
||||
}
|
||||
|
||||
public void addField(String key, long id) {
|
||||
fields.put(key, id);
|
||||
}
|
||||
}
|
||||
21
src/main/java/org/bdware/sc/memory/MemoryObject.java
Normal file
21
src/main/java/org/bdware/sc/memory/MemoryObject.java
Normal file
@@ -0,0 +1,21 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class MemoryObject implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = -7830175031856452056L;
|
||||
public long id;
|
||||
public MOType type;
|
||||
Object data;
|
||||
|
||||
public MemoryObject(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return JsonUtil.toJson(this);
|
||||
}
|
||||
}
|
||||
160
src/main/java/org/bdware/sc/memory/MemoryRecoverUtil.java
Normal file
160
src/main/java/org/bdware/sc/memory/MemoryRecoverUtil.java
Normal file
@@ -0,0 +1,160 @@
|
||||
package org.bdware.sc.memory;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.boundry.Resources;
|
||||
import org.bdware.sc.util.JsonUtil;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.Invocable;
|
||||
import javax.script.ScriptContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class MemoryRecoverUtil {
|
||||
NashornScriptEngine engine;
|
||||
String loadContent;
|
||||
MemoryDump memoryDump = null;
|
||||
Resources resource;
|
||||
|
||||
public MemoryRecoverUtil(NashornScriptEngine en, Resources r) {
|
||||
this.engine = en;
|
||||
this.resource = r;
|
||||
}
|
||||
|
||||
//支持传入memory文件路径或者直接是memory的字符串
|
||||
public void loadMemory(String path, boolean stateful) {
|
||||
synchronized (engine) {
|
||||
File file = new File(path);
|
||||
try {
|
||||
if (file.exists()) {
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
ObjectInputStream reader = new ObjectInputStream(gzin);
|
||||
|
||||
// MemoryDump temp = new MemoryDump();
|
||||
// temp.objects = (Map<Long, MemoryObject>) reader.readObject();
|
||||
// String content = JsonUtil.toPrettyJson(temp);
|
||||
|
||||
MemoryDump temp = (MemoryDump) reader.readObject();
|
||||
String content = JsonUtil.toPrettyJson(temp.objects);
|
||||
temp.jseDump.printContent();
|
||||
long invokeID = temp.jseDump.invokeID;
|
||||
int copies = temp.jseDump.numsOfCopies;
|
||||
long formerInvokeID = JavaScriptEntry.invokeID;
|
||||
JavaScriptEntry.invokeID = invokeID;
|
||||
JavaScriptEntry.numOfCopies = copies;
|
||||
if (JavaScriptEntry.random == null) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(temp.jseDump.ranSeed);
|
||||
}
|
||||
if (formerInvokeID > invokeID) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(temp.jseDump.ranSeed);
|
||||
for (long i = 0; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
} else {
|
||||
for (long i = formerInvokeID; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
//memoryDump = MemoryDump.loadFromStr(content);
|
||||
if (stateful) {
|
||||
memoryDump = temp;
|
||||
}
|
||||
reader.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else { //直接传入的是字符串
|
||||
String[] strs = path.split("--seperate--");
|
||||
String content = strs[0];
|
||||
String jse = strs[1];
|
||||
System.out.println("MemoryRecover从字符串load:\n" + content + "\n" + jse);
|
||||
String strs2[] = jse.split(";");
|
||||
long invokeID = Long.parseLong(strs2[0]);
|
||||
int copies = Integer.parseInt(strs2[2]);
|
||||
long formerInvokeID = JavaScriptEntry.invokeID;
|
||||
String contractID = strs2[1];
|
||||
JavaScriptEntry.invokeID = invokeID;
|
||||
JavaScriptEntry.numOfCopies = copies;
|
||||
if (JavaScriptEntry.random == null) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(Integer.valueOf(contractID));
|
||||
}
|
||||
if (formerInvokeID > invokeID) {
|
||||
JavaScriptEntry.random = new Random();
|
||||
JavaScriptEntry.random.setSeed(Integer.valueOf(contractID));
|
||||
for (long i = 0; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
} else {
|
||||
for (long i = formerInvokeID; i < invokeID; i++) {
|
||||
JavaScriptEntry.random.nextInt();
|
||||
}
|
||||
}
|
||||
|
||||
if (stateful) { //有状态合约
|
||||
memoryDump = MemoryDump.loadFromStr(content);
|
||||
}
|
||||
}
|
||||
|
||||
if (stateful) {
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
Map<Long, Object> objects = memoryDump.recreateObject();
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) objects.get(0L);
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
for (Object key : global.keySet()) {
|
||||
if (global.get(key) != null) bindings.put((String) key, global.get(key));
|
||||
}
|
||||
}
|
||||
this.memoryDump = null;
|
||||
if (resource != null)
|
||||
((Invocable) engine).invokeFunction("defineProp", "Resources", resource);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
public void loadMemory(String path) {
|
||||
try {
|
||||
String memory;
|
||||
File mem = new File(path);
|
||||
FileInputStream fileout = new FileInputStream(mem);
|
||||
ObjectInputStream reader = new ObjectInputStream(fileout);
|
||||
loadContent = (String) reader.readObject();
|
||||
// System.out.println("[MemoryRecoverUtil] loadContent : \n" + loadContent);
|
||||
reader.close();
|
||||
memoryDump = MemoryDump.loadFromStr(loadContent);
|
||||
|
||||
|
||||
String ret = JsonUtil.toPrettyJson(memoryDump);
|
||||
MemoryJSObject root = memoryDump.getRoot();
|
||||
Map<Long, Object> objects = memoryDump.recreateObject();
|
||||
ScriptObjectMirror global = (ScriptObjectMirror) objects.get(0L);
|
||||
Bindings bindings = engine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
for (Object key : global.keySet()) {
|
||||
if (global.get(key) != null)
|
||||
bindings.put((String) key, global.get(key));
|
||||
}
|
||||
this.memoryDump = null;
|
||||
if (resource != null)
|
||||
((Invocable) engine).invokeFunction("defineProp", "Resources", resource);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
181
src/main/java/org/bdware/sc/redo/TransRecordUtil.java
Normal file
181
src/main/java/org/bdware/sc/redo/TransRecordUtil.java
Normal file
@@ -0,0 +1,181 @@
|
||||
package org.bdware.sc.redo;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import org.bdware.sc.engine.SyncMechUtil;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.TreeMap;
|
||||
|
||||
public class TransRecordUtil {
|
||||
public static final int RESERVED = 20; //最近的多少次records内存也保存,如果一个节点距离集群当前的seq相差超过这个值,就不从本地恢复,让别的节点现场dump
|
||||
public static final int DUMP_PERIOD = 50; //每满50次记录,就记录一次全量状态,清一次trans记录
|
||||
private static final Logger LOGGER = LogManager.getLogger(TransRecordUtil.class);
|
||||
public Map<Integer, TransRecord> cacheTransRecords = new TreeMap<Integer, TransRecord>(); //TODO 认为其中records一定是seq连续的,否则可能有问题?
|
||||
//public PriorityQueue<TransRecord> transRecords = new PriorityQueue<TransRecord>();
|
||||
public TransRecord currentTransRecord;
|
||||
SyncMechUtil syncUtil;
|
||||
DesktopEngine engine;
|
||||
String fileName;
|
||||
|
||||
public TransRecordUtil(DesktopEngine en, SyncMechUtil sync) {
|
||||
this.engine = en;
|
||||
syncUtil = sync;
|
||||
}
|
||||
|
||||
public void setFileName(String path) {
|
||||
fileName = path;
|
||||
}
|
||||
|
||||
//每次事务开始时初始化
|
||||
public void startNext(String fun, String arg, int sequence) {
|
||||
//logger.debug("TransRecordUtil 开始记录事务");
|
||||
currentTransRecord = new TransRecord(fun, arg, sequence);
|
||||
}
|
||||
|
||||
public void startNext(String fun, String arg) {
|
||||
//logger.debug("TransRecordUtil 开始记录事务");
|
||||
currentTransRecord = new TransRecord(fun, arg);
|
||||
}
|
||||
|
||||
//每次事务结束时记录
|
||||
public synchronized void eachFinish() {
|
||||
//logger.debug("TransRecordUtil 记录完一个事务 \n" + currentTransRecord.toString());
|
||||
cacheTransRecords.put(currentTransRecord.seq, currentTransRecord);
|
||||
if (cacheTransRecords.size() == RESERVED) {
|
||||
int temp = 0;
|
||||
for (Integer i : cacheTransRecords.keySet()) {
|
||||
temp = i;
|
||||
break;
|
||||
}
|
||||
cacheTransRecords.remove(temp);
|
||||
}
|
||||
|
||||
appendTransFile(currentTransRecord); //执行前已经定序了,所以trans其实没必要定序
|
||||
}
|
||||
|
||||
//追加写入最后一个TransRecord
|
||||
public void appendTransFile(TransRecord record) {
|
||||
syncUtil.filedTrans.getAndIncrement();
|
||||
|
||||
File file = new File(syncUtil.transDir + "/" + fileName);
|
||||
File parent = file.getParentFile();
|
||||
if (parent.isDirectory() && !parent.exists()) {
|
||||
parent.mkdirs();
|
||||
}
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(record.toString());
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//自动触发检查点
|
||||
if (syncUtil.filedTrans.get() == DUMP_PERIOD) {
|
||||
LOGGER.info("自动触发检查点 DUMP_PERIOD=" + DUMP_PERIOD);
|
||||
file = new File(syncUtil.memoryDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
file = new File(syncUtil.traceDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
file = new File(syncUtil.transDir);
|
||||
if (file.isDirectory()) {
|
||||
String[] children = file.list();
|
||||
for (int i = 0; i < children.length; i++) {
|
||||
File temp = new File(file, children[i]);
|
||||
temp.delete();
|
||||
}
|
||||
}
|
||||
|
||||
//sync文件删除第2,3行
|
||||
file = new File(syncUtil.syncDir + "/" + syncUtil.syncFileName);
|
||||
String firstLine = "";
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = "";
|
||||
while ((line = br.readLine()) != null) {
|
||||
firstLine = line;
|
||||
break;
|
||||
}
|
||||
br.close();
|
||||
fr.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
file.delete();
|
||||
file = new File(syncUtil.syncDir + "/" + syncUtil.syncFileName);
|
||||
|
||||
try {
|
||||
FileWriter fw = new FileWriter(file, true);
|
||||
PrintWriter pw = new PrintWriter(fw);
|
||||
pw.println(firstLine);
|
||||
pw.flush();
|
||||
fw.flush();
|
||||
pw.close();
|
||||
fw.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
syncUtil.setStartFlag(true);
|
||||
}
|
||||
}
|
||||
|
||||
//record executeContract in current trans
|
||||
public void recordExecutes(String k, String v) {
|
||||
if (currentTransRecord != null) {
|
||||
currentTransRecord.executes.put(k, v);
|
||||
} else {
|
||||
LOGGER.info("[TransRecordUtil] recordExecutes error!");
|
||||
}
|
||||
}
|
||||
|
||||
public String getCachedTransRecords(int start) {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
//先查看有没有第1个
|
||||
if (!cacheTransRecords.containsKey(start))
|
||||
return "";
|
||||
|
||||
synchronized (cacheTransRecords) {
|
||||
int temp = -1;
|
||||
int j = start - 1;//确保有从start开始的连续trans,j记录上一个i值
|
||||
for (Integer i : cacheTransRecords.keySet()) {
|
||||
if (i >= start) {
|
||||
if (i == (j + 1)) {
|
||||
str.append(cacheTransRecords.get(i).toString() + "\n");
|
||||
temp = Math.max(temp, i);
|
||||
j = i;
|
||||
} else {
|
||||
LOGGER.info("i=" + i + " j=" + j + " 不连续");
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (temp != -1)
|
||||
str.append("==>>" + temp);
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
100
src/main/java/org/bdware/sc/redo/TransRecoverUtil.java
Normal file
100
src/main/java/org/bdware/sc/redo/TransRecoverUtil.java
Normal file
@@ -0,0 +1,100 @@
|
||||
package org.bdware.sc.redo;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.bdware.sc.ContractResult;
|
||||
import org.bdware.sc.bean.ContractRequest;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TransRecoverUtil {
|
||||
private static final Logger LOGGER = LogManager.getLogger(TransRecoverUtil.class);
|
||||
public ArrayList<TransRecord> transRecords;
|
||||
public TransRecord curRecoverRecord;
|
||||
DesktopEngine engine;
|
||||
|
||||
public TransRecoverUtil(DesktopEngine en) {
|
||||
this.engine = en;
|
||||
transRecords = new ArrayList<TransRecord>();
|
||||
}
|
||||
|
||||
public void setTraceRecords(String fileName) {
|
||||
TransRecord cur_read = null;
|
||||
File file = new File(fileName);
|
||||
|
||||
try {
|
||||
FileReader fr = new FileReader(file);
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line = "";
|
||||
String[] arrs = null;
|
||||
while ((line = br.readLine()) != null) {
|
||||
String[] strs = line.split(";");
|
||||
String arg;
|
||||
if (strs.length < 5) { //调用记录参数为空
|
||||
arg = null;
|
||||
} else {
|
||||
arg = strs[4];
|
||||
}
|
||||
|
||||
if (strs[0].equals("===TransRecord===")) {
|
||||
if (cur_read != null) {
|
||||
transRecords.add(cur_read);
|
||||
System.out.println("恢复时加入 " + cur_read.toString());
|
||||
}
|
||||
if (strs[1].equals("true"))
|
||||
cur_read = new TransRecord(strs[3], arg, Integer.parseInt(strs[2]));
|
||||
else
|
||||
cur_read = new TransRecord(strs[3], arg);
|
||||
} else {
|
||||
cur_read.addExecutes(strs[0], strs[1]);
|
||||
}
|
||||
}
|
||||
if (cur_read != null) {
|
||||
transRecords.add(cur_read);
|
||||
System.out.println("恢复时加入 " + cur_read.toString());
|
||||
}
|
||||
br.close();
|
||||
fr.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void recoverFromTransRecord() {
|
||||
synchronized (engine) {
|
||||
engine.setRecovering(true);
|
||||
for (int i = 0; i < transRecords.size(); i++) {
|
||||
curRecoverRecord = transRecords.get(i);
|
||||
String funName = curRecoverRecord.getFuncName();
|
||||
String arg = curRecoverRecord.getArg();
|
||||
|
||||
ContractRequest ac = null;
|
||||
ac = new ContractRequest();
|
||||
ac.setAction(funName);
|
||||
ac.setArg(arg);
|
||||
ac.needSeq = curRecoverRecord.needSeq;
|
||||
if (ac.needSeq) {
|
||||
ac.seq = curRecoverRecord.seq;
|
||||
LOGGER.info("[TransRecordUtil] redo 重新执行事务 " + ac.seq);
|
||||
}
|
||||
System.out.println("[TransRecoverUtil] recover " + ac.needSeq + " " + ac.seq + " " + ac.getAction() + " " + ac.getArg());
|
||||
|
||||
ContractResult result = engine.executeContract(ac);
|
||||
|
||||
if (result.status != ContractResult.Status.Success) {
|
||||
System.out.println("[错误]" + result.status);
|
||||
}
|
||||
}
|
||||
engine.setRecovering(false);
|
||||
}
|
||||
}
|
||||
|
||||
//TODO
|
||||
public void recoverFromATransRecord(TransRecord record) {
|
||||
|
||||
}
|
||||
}
|
||||
24
src/main/java/org/bdware/sc/syncMech/EstimateUtil.java
Normal file
24
src/main/java/org/bdware/sc/syncMech/EstimateUtil.java
Normal file
@@ -0,0 +1,24 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
public class EstimateUtil {
|
||||
public static final String DUMP_TIME = "dumpTime";
|
||||
public static final String DUMP_TIMES = "dumpTimes";
|
||||
long dumpTime; //用时
|
||||
long dumpTimes; //次数
|
||||
long dumpFile; //状态大小,dumpFile的次数也是dumpTimes
|
||||
|
||||
public static final String LOADMEMORY_TIME = "loadMemoryTime";
|
||||
public static final String LOADMEMORY_TIMES = "loadMemoryTimes";
|
||||
long loadMemoryTime;
|
||||
long loadMemoryTimes;
|
||||
|
||||
public static final String EXECUTE_TIME = "executeTime";
|
||||
public static final String EXECUTE_TIMES = "executeTimes";
|
||||
long executeTime;
|
||||
long executeTimes;
|
||||
|
||||
public static final String REDO_TRANS_FILE = "redoTransFile";
|
||||
public static final String REDO_TRANS_TIMES = "redoTransTimes";
|
||||
long redoTransFIle;
|
||||
long redoTransTimes;
|
||||
}
|
||||
44
src/main/java/org/bdware/sc/syncMech/SyncRecord.java
Normal file
44
src/main/java/org/bdware/sc/syncMech/SyncRecord.java
Normal file
@@ -0,0 +1,44 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class SyncRecord implements Serializable{
|
||||
SyncType type;
|
||||
String fileName; //eg:/memory/2020-...
|
||||
|
||||
public SyncRecord(SyncType t) {
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
public SyncRecord(SyncType t,String str){
|
||||
type = t;
|
||||
fileName = str;
|
||||
}
|
||||
|
||||
public void setType(SyncType ty) {
|
||||
this.type = ty;
|
||||
}
|
||||
|
||||
public SyncType getType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
public void setFileName(String file) {
|
||||
this.fileName = file;
|
||||
}
|
||||
|
||||
public String getFileName() {
|
||||
return this.fileName;
|
||||
}
|
||||
|
||||
public String getContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append(type.toString() + ";" + fileName);
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static SyncRecord loadFromString(String str){
|
||||
String[] strs = str.split(";");
|
||||
return new SyncRecord(SyncType.convert(strs[0]),strs[1]);
|
||||
}
|
||||
}
|
||||
20
src/main/java/org/bdware/sc/syncMech/SyncType.java
Normal file
20
src/main/java/org/bdware/sc/syncMech/SyncType.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.bdware.sc.syncMech;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public enum SyncType implements Serializable{
|
||||
Memory, Trace, Trans;
|
||||
|
||||
public static SyncType convert(String str){
|
||||
switch (str){
|
||||
case "Memory":
|
||||
return Memory;
|
||||
case "Trace":
|
||||
return Trace;
|
||||
case "Trans":
|
||||
return Trans;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/main/java/org/bdware/sc/trace/JS.java
Normal file
7
src/main/java/org/bdware/sc/trace/JS.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JS implements Serializable{
|
||||
|
||||
}
|
||||
10
src/main/java/org/bdware/sc/trace/JSArray.java
Normal file
10
src/main/java/org/bdware/sc/trace/JSArray.java
Normal file
@@ -0,0 +1,10 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSArray extends JSScript implements Serializable{
|
||||
|
||||
public JSArray(int id) {
|
||||
this.objID = id;
|
||||
}
|
||||
}
|
||||
7
src/main/java/org/bdware/sc/trace/JSNull.java
Normal file
7
src/main/java/org/bdware/sc/trace/JSNull.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSNull extends JS implements Serializable{
|
||||
|
||||
}
|
||||
14
src/main/java/org/bdware/sc/trace/JSObject.java
Normal file
14
src/main/java/org/bdware/sc/trace/JSObject.java
Normal file
@@ -0,0 +1,14 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/*
|
||||
* js中对象
|
||||
* ScriptObject JO
|
||||
*/
|
||||
public class JSObject extends JSScript implements Serializable{
|
||||
|
||||
public JSObject(int id) {
|
||||
this.objID = id;
|
||||
}
|
||||
}
|
||||
11
src/main/java/org/bdware/sc/trace/JSScript.java
Normal file
11
src/main/java/org/bdware/sc/trace/JSScript.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSScript extends JS implements Serializable{
|
||||
int objID;
|
||||
|
||||
public int getObjID() {
|
||||
return this.objID;
|
||||
}
|
||||
}
|
||||
7
src/main/java/org/bdware/sc/trace/JSUndifined.java
Normal file
7
src/main/java/org/bdware/sc/trace/JSUndifined.java
Normal file
@@ -0,0 +1,7 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class JSUndifined extends JS implements Serializable{
|
||||
|
||||
}
|
||||
77
src/main/java/org/bdware/sc/trace/MethodInvokePrinter.java
Normal file
77
src/main/java/org/bdware/sc/trace/MethodInvokePrinter.java
Normal file
@@ -0,0 +1,77 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.PrintStream;
|
||||
import java.util.Set;
|
||||
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceMethod;
|
||||
|
||||
public class MethodInvokePrinter implements TraceMethod {
|
||||
|
||||
PrintStream out;
|
||||
|
||||
public void printObject(final Object arg) {
|
||||
if (arg instanceof ScriptObject) {
|
||||
final ScriptObject object = (ScriptObject) arg;
|
||||
|
||||
boolean isFirst = true;
|
||||
final Set<Object> keySet = object.keySet();
|
||||
|
||||
if (keySet.isEmpty()) {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
} else {
|
||||
out.print("{ ");
|
||||
|
||||
for (final Object key : keySet) {
|
||||
if (!isFirst) {
|
||||
out.print(", ");
|
||||
}
|
||||
|
||||
out.print(key);
|
||||
out.print(":");
|
||||
|
||||
final Object value = object.get(key);
|
||||
|
||||
if (value instanceof ScriptObject) {
|
||||
out.print("...");
|
||||
} else {
|
||||
printObject(value);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
out.print(" }");
|
||||
}
|
||||
} else {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
}
|
||||
}
|
||||
|
||||
public void tracePrint(final String tag, int pc, String methodName, final Object[] args, final Object result) {
|
||||
// boolean isVoid = type().returnType() == void.class;
|
||||
out.print(tag);
|
||||
out.print(methodName + "_" + pc + "(");
|
||||
if (args.length > 0) {
|
||||
printObject(args[0]);
|
||||
for (int i = 1; i < args.length; i++) {
|
||||
final Object arg = args[i];
|
||||
out.print(", ");
|
||||
|
||||
if (!(arg instanceof ScriptObject && ((ScriptObject) arg).isScope())) {
|
||||
printObject(arg);
|
||||
} else {
|
||||
out.print("SCOPE");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.print(")");
|
||||
if (tag.equals("EXIT ")) {
|
||||
out.print(" --> ");
|
||||
printObject(result);
|
||||
}
|
||||
out.println();
|
||||
}
|
||||
|
||||
}
|
||||
212
src/main/java/org/bdware/sc/trace/ProgramPointCounter.java
Normal file
212
src/main/java/org/bdware/sc/trace/ProgramPointCounter.java
Normal file
@@ -0,0 +1,212 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.JsonParser;
|
||||
import com.sun.mail.iap.ByteArray;
|
||||
import org.bdware.analysis.CFGraph;
|
||||
import org.bdware.sc.ContractProcess;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptRuntime;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceMethod;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
|
||||
public class ProgramPointCounter extends ContractProcess.Logger implements TraceMethod {
|
||||
public long gasLimit;
|
||||
public long extraGas;
|
||||
// PrintStream out;
|
||||
ByteArrayOutputStream bo;
|
||||
HashMap<Integer, Map<String, Integer>> ppc = new HashMap<>();
|
||||
String globalAction;
|
||||
HashMap<String, CFGraph> cfgMap;
|
||||
HashMap<String, Long> countMap;
|
||||
int functionIndex = 0;
|
||||
public long gasValue = 0;
|
||||
|
||||
public ProgramPointCounter(
|
||||
ByteArrayOutputStream bo,
|
||||
ContractProcess cp,
|
||||
long gasLimit,
|
||||
int functionIndex,
|
||||
long gasValue,
|
||||
long extraGas,
|
||||
String action,
|
||||
HashMap<String, Long> countMap) {
|
||||
super(new PrintStream(bo), cp);
|
||||
// out = System.out;
|
||||
this.bo = bo;
|
||||
globalAction = action;
|
||||
this.gasLimit = gasLimit - extraGas;
|
||||
this.functionIndex = functionIndex;
|
||||
this.countMap = countMap;
|
||||
this.gasValue = gasValue - extraGas;
|
||||
this.extraGas = extraGas;
|
||||
}
|
||||
|
||||
boolean simple = true;
|
||||
|
||||
@Override
|
||||
public String getOutputStr() {
|
||||
return bo.toString();
|
||||
}
|
||||
/*
|
||||
private void printObject(final Object arg) {
|
||||
if (simple) return;
|
||||
if (arg instanceof ScriptObject) {
|
||||
final ScriptObject object = (ScriptObject) arg;
|
||||
|
||||
boolean isFirst = true;
|
||||
final Set<Object> keySet = object.keySet();
|
||||
// System.out.println("[keySet:]");
|
||||
if (keySet.isEmpty()) {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
} else {
|
||||
out.print("{ ");
|
||||
|
||||
for (final Object key : keySet) {
|
||||
if (!isFirst) {
|
||||
out.print(", ");
|
||||
}
|
||||
|
||||
out.print(key);
|
||||
out.print(":");
|
||||
|
||||
final Object value = object.get(key);
|
||||
|
||||
if (value instanceof ScriptObject) {
|
||||
out.print("...");
|
||||
} else {
|
||||
printObject(value);
|
||||
}
|
||||
|
||||
isFirst = false;
|
||||
}
|
||||
|
||||
out.print(" }");
|
||||
}
|
||||
} else {
|
||||
out.print(ScriptRuntime.safeToString(arg));
|
||||
}
|
||||
}
|
||||
*/
|
||||
boolean initEnter = false;
|
||||
Stack<Integer> pcStack = new Stack<>();
|
||||
|
||||
@Override
|
||||
public void tracePrint(
|
||||
final String tag, int pc, String methodName, final Object[] args, final Object result) {
|
||||
// System.out.println("!@#$%^&*" + tag + pc + methodName + args + result);
|
||||
if (!initEnter) {
|
||||
// System.out.println("[functionIndex]:" + countMap.get(String.valueOf(functionIndex)));
|
||||
compareValue(String.valueOf(functionIndex));
|
||||
initEnter = true;
|
||||
}
|
||||
|
||||
if (tag.equals("EXIT ")) {
|
||||
// System.out.println(tag);
|
||||
if (pc == pcStack.peek()) {
|
||||
// System.out.println("出栈之前" + pcStack);
|
||||
pcStack.pop();
|
||||
if (countMap.containsKey(String.valueOf(pc))) {
|
||||
// System.out.println("出栈之后" + pcStack);
|
||||
compareValue(String.valueOf(pc));
|
||||
// System.out.println("弹出之后的消耗" + gasValue);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// System.out.println(tag);
|
||||
pcStack.push(pc);
|
||||
// System.out.println("入栈" + pcStack);
|
||||
}
|
||||
// out.print("[ProgramPointCounter] " + tag);
|
||||
// out.print(methodName + "_" + pc + "(");
|
||||
|
||||
// if (args.length > 0) {
|
||||
// printObject(args[0]);
|
||||
// for (int i = 1; i < args.length; i++) {
|
||||
// final Object arg = args[i];
|
||||
// out.print(", ");
|
||||
// if (!(arg instanceof ScriptObject && ((ScriptObject) arg).isScope())) {
|
||||
// printObject(arg);
|
||||
// } else {
|
||||
// out.print("SCOPE");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// out.print(")");
|
||||
// if (tag.equals("EXIT ")) {
|
||||
// out.print(" --> ");
|
||||
// printObject(result);
|
||||
// System.out.println("[result:]" + result);
|
||||
// }
|
||||
// out.println();
|
||||
// System.out.println("[Fee剩余]" + gasValue);
|
||||
}
|
||||
|
||||
public long cost = 0;
|
||||
|
||||
private void compareValue(String index) {
|
||||
if (gasValue > gasLimit) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("gas out of limit");
|
||||
}
|
||||
cost = cost + countMap.get(index);
|
||||
// System.out.println("gasValue --:" + gasValue + " -" + countMap.get(index));
|
||||
|
||||
gasValue = gasValue - countMap.get(index);
|
||||
gasLimit = gasLimit - countMap.get(index);
|
||||
if (gasValue <= 0) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("run out of InsnFee");
|
||||
} else if (gasLimit <= 0) {
|
||||
System.out.println("out of gas");
|
||||
throw new IllegalStateException("run over the limit");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void println(String s) {
|
||||
super.println(s);
|
||||
// System.out.print("[s是:]"+s);
|
||||
// count++;
|
||||
// String oldTrace=traceCompare(s);
|
||||
// +=当前if与之前的if的指令权重或是指令数量。
|
||||
// if (count > 10) {
|
||||
// throw new IllegalStateException("run out of gas");
|
||||
// }
|
||||
try {
|
||||
JsonObject jo = new JsonParser().parse(s).getAsJsonObject();
|
||||
String traceMarkValue = jo.get("traceMark").getAsString();
|
||||
String val = jo.get("val").getAsString();
|
||||
// System.out.println(countMap);
|
||||
for (Map.Entry<String, Long> test : countMap.entrySet()) {
|
||||
if (test.getKey().contains(traceMarkValue)) {
|
||||
if (Integer.valueOf(val) <= 0 && test.getKey().contains("false")) {
|
||||
// System.out.println("false" + test.getKey());
|
||||
compareValue(test.getKey());
|
||||
} else if (Integer.valueOf(val) > 0 && test.getKey().contains("true")) {
|
||||
// System.out.println("true" + test.getKey());
|
||||
compareValue(test.getKey());
|
||||
// System.out.println("[gasLimit]"+gasValue+"[gasLimit]"+gasLimit);
|
||||
}
|
||||
}
|
||||
}
|
||||
// System.out.println("[Gas剩余]" + gasValue);
|
||||
// System.out.println("[执行消耗Gas]" + cost);
|
||||
// System.out.println("[额外Gas]" + extraGas);
|
||||
// System.out.println(
|
||||
// "[ProgramPointCounter] {\"traceMark\":"
|
||||
// + traceMarkValue
|
||||
// + "\"val\":"
|
||||
// + val
|
||||
// + "}");
|
||||
} catch (IllegalStateException e) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
11
src/main/java/org/bdware/sc/trace/Trace.java
Normal file
11
src/main/java/org/bdware/sc/trace/Trace.java
Normal file
@@ -0,0 +1,11 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class Trace implements Serializable{
|
||||
|
||||
public String traceContent() {
|
||||
return "Trace Content";
|
||||
}
|
||||
|
||||
}
|
||||
20
src/main/java/org/bdware/sc/trace/TraceDone.java
Normal file
20
src/main/java/org/bdware/sc/trace/TraceDone.java
Normal file
@@ -0,0 +1,20 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TraceDone extends Trace implements Serializable {
|
||||
int id;
|
||||
|
||||
public TraceDone(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getID() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent() {
|
||||
return "[TraceDone] allocID:" + id + "\n";
|
||||
}
|
||||
}
|
||||
51
src/main/java/org/bdware/sc/trace/TraceInitArray.java
Normal file
51
src/main/java/org/bdware/sc/trace/TraceInitArray.java
Normal file
@@ -0,0 +1,51 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* 数组创建时有初始值,进行初始化
|
||||
*/
|
||||
public class TraceInitArray extends Trace implements Serializable{
|
||||
int arrayId; //被初始化的数组id
|
||||
List<Object> keys = new ArrayList<Object>(); //数组下标可能是整数,对象名等
|
||||
List<Object> values = new ArrayList<Object>(); //数组内内容
|
||||
|
||||
public TraceInitArray(int id) {
|
||||
this.arrayId = id;
|
||||
keys = new ArrayList<Object>();
|
||||
values = new ArrayList<Object>();
|
||||
}
|
||||
|
||||
public void put(Object key,Object value) {
|
||||
keys.add(key);
|
||||
values.add(value);
|
||||
}
|
||||
|
||||
public int getLength() {
|
||||
return values.size();
|
||||
}
|
||||
|
||||
public int getArrayId() {
|
||||
return this.arrayId;
|
||||
}
|
||||
|
||||
public Object getKey(int i) {
|
||||
return keys.get(i);
|
||||
}
|
||||
|
||||
public Object getValue(int i) {
|
||||
return values.get(i);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent(){
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceInitArray]\n");
|
||||
str.append("ArrayID=" + arrayId + "\n");
|
||||
for(int i = 0;i < values.size();i++)
|
||||
str.append("key=" + keys.get(i) + ";value=" + values.get(i) + "\n");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
29
src/main/java/org/bdware/sc/trace/TraceInitObject.java
Normal file
29
src/main/java/org/bdware/sc/trace/TraceInitObject.java
Normal file
@@ -0,0 +1,29 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class TraceInitObject extends Trace implements Serializable{
|
||||
int id;
|
||||
int id2;
|
||||
|
||||
public TraceInitObject(int id,int id2) {
|
||||
this.id = id;
|
||||
this.id2 = id2;
|
||||
}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getId2() {
|
||||
return id2;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceInitObject]\n");
|
||||
str.append("id=" + id + " ; id2=" + id2 + "\n");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
38
src/main/java/org/bdware/sc/trace/TraceRecord.java
Normal file
38
src/main/java/org/bdware/sc/trace/TraceRecord.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class TraceRecord implements Serializable{
|
||||
private static final long serialVersionUID = 34643133713102276L;
|
||||
|
||||
public List<Trace> traces;
|
||||
|
||||
public TraceRecord() {
|
||||
traces = new ArrayList<Trace>();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
for(int i = 0;i < traces.size();i++) {
|
||||
//str.append("com/yancloud/sc/trace" + i + ":\n");
|
||||
str.append(traces.get(i).traceContent() + "\n");
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* 加入一条新的trace
|
||||
*/
|
||||
public void record(Trace trace) {
|
||||
traces.add(trace);
|
||||
}
|
||||
|
||||
public int length() {
|
||||
return traces.size();
|
||||
}
|
||||
}
|
||||
249
src/main/java/org/bdware/sc/trace/TraceRecordUtil.java
Normal file
249
src/main/java/org/bdware/sc/trace/TraceRecordUtil.java
Normal file
@@ -0,0 +1,249 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
import org.bdware.sc.engine.SyncMechUtil;
|
||||
import wrp.jdk.nashorn.internal.objects.NativeArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.ConsString;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.JSType;
|
||||
import wrp.jdk.nashorn.internal.runtime.PropertyMap;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceSetBehavior;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceSetupArray;
|
||||
import wrp.jdk.nashorn.internal.runtime.TraceSetupScriptObject;
|
||||
import wrp.jdk.nashorn.internal.runtime.arrays.ArrayData;
|
||||
|
||||
public class TraceRecordUtil {
|
||||
SyncMechUtil syncUtil;
|
||||
DesktopEngine engine;
|
||||
|
||||
public ArrayList<TraceRecord> traceRecords;
|
||||
|
||||
public TraceRecord currentTraceRecord; //当前事务中所有非TraceSet的trace
|
||||
public Map<Integer,TraceInitArray> currentArrayMap;
|
||||
public Map<TraceSetIdentifier,TraceSet> currentMap; //当前事务中所有TraceSet的精简记录
|
||||
|
||||
public TraceRecordUtil(DesktopEngine de,SyncMechUtil sync) {
|
||||
this.engine = de;
|
||||
this.syncUtil = sync;
|
||||
}
|
||||
|
||||
public ArrayList<TraceRecord> getTraceRecords() {
|
||||
if (traceRecords == null) {
|
||||
return null;
|
||||
}
|
||||
return this.traceRecords;
|
||||
}
|
||||
|
||||
public TraceRecord getTraceRecord(int c) {
|
||||
if (traceRecords == null)
|
||||
return null;
|
||||
else if (traceRecords.size() <= c)
|
||||
return null;
|
||||
else
|
||||
return traceRecords.get(c);
|
||||
}
|
||||
|
||||
public String getTraceRecordsContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < traceRecords.size(); i++) {
|
||||
str.append("No." + i + "record : \n" + traceRecords.get(i).toString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public static String getTraceRecordsByFile(String fileName) {
|
||||
ArrayList<TraceRecord> traceRecords = null;
|
||||
File file = new File(fileName);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
reader = new ObjectInputStream(gzin);
|
||||
traceRecords = (ArrayList<TraceRecord>) reader.readObject();
|
||||
reader.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
StringBuilder str = new StringBuilder();
|
||||
for (int i = 0; i < traceRecords.size(); i++) {
|
||||
str.append("No." + i + "record : \n" + traceRecords.get(i).toString());
|
||||
}
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
//添加简化过的TraceSet
|
||||
public void addSmpSet() {
|
||||
currentTraceRecord.traces.addAll(currentArrayMap.values());
|
||||
currentTraceRecord.traces.addAll(currentMap.values());
|
||||
}
|
||||
|
||||
public void saveTraceRecords(String fileName) {
|
||||
if (traceRecords == null) {
|
||||
System.out.println("[saveTraceRecords] traceRecords is null,can't save traceRecords to fill!");
|
||||
}
|
||||
|
||||
File traceFile = new File(fileName + ".trace"); // trace文件名中不带时间
|
||||
File parent = traceFile.getParentFile();
|
||||
if (!parent.exists())
|
||||
parent.mkdirs();
|
||||
|
||||
ObjectOutputStream writer;
|
||||
try {
|
||||
FileOutputStream fileout = new FileOutputStream(traceFile);
|
||||
GZIPOutputStream out = new GZIPOutputStream(fileout);
|
||||
writer = new ObjectOutputStream(out);
|
||||
writer.writeObject(traceRecords);
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void startRecordTrace() {
|
||||
this.traceRecords = new ArrayList<TraceRecord>();
|
||||
// recording = true;
|
||||
|
||||
//set behavior
|
||||
Context.TRACESETBEHAVIOR = new TraceSetBehavior() {
|
||||
|
||||
@Override
|
||||
public void trace(CallSiteDescriptor desc, Object... args) {
|
||||
int id = ((ScriptObject) args[0]).getObjectID();
|
||||
Object key = null;
|
||||
Object value = null;
|
||||
|
||||
if (args.length == 3) {
|
||||
key = JSType.toPrimitive(args[1]);
|
||||
value = args[2];
|
||||
} else if (args.length == 2) {
|
||||
key = desc.getName().split(":")[2];
|
||||
value = args[1];
|
||||
}
|
||||
|
||||
if (value instanceof Integer || value instanceof String || value instanceof Double)
|
||||
;
|
||||
else if (value instanceof ConsString)
|
||||
value = value.toString();
|
||||
else
|
||||
value = produceJS(value);
|
||||
|
||||
currentMap.put(new TraceSetIdentifier(id,key),new TraceSet(id,key,value));
|
||||
}
|
||||
};
|
||||
|
||||
//setup script object
|
||||
Context.TRACESETUPSCRIPTOBJECT = new TraceSetupScriptObject() {
|
||||
|
||||
@Override
|
||||
public void trace(ScriptObject arg, PropertyMap map) {
|
||||
/*
|
||||
* TraceSetup tracesetup = new TraceSetup((JSScript)produceJS(arg));
|
||||
* traceRecord.record(tracesetup);
|
||||
*/
|
||||
|
||||
TraceSetup tracesetup = new TraceSetup((JSScript) produceJS(arg));
|
||||
|
||||
/*
|
||||
* System.out.println("[startRecord] setupScriptObject argID=" +
|
||||
* arg.getObjectID() + " map=" + map.size()); Iterator<String> keys =
|
||||
* arg.propertyIterator(); while(keys.hasNext()) { String key = keys.next();
|
||||
* System.out.println(key + " ; " +
|
||||
* map.findProperty(key).getClass().getCanonicalName());
|
||||
* tracesetup.add(map.findProperty(key)); }
|
||||
*/
|
||||
|
||||
currentTraceRecord.record(tracesetup);
|
||||
}
|
||||
};
|
||||
|
||||
//setup array
|
||||
Context.TRACESETUPARRAY = new TraceSetupArray() {
|
||||
@Override
|
||||
public void trace(ArrayData arg, int id) {
|
||||
TraceInitArray traceinitarray = new TraceInitArray(id);
|
||||
for (int i = 0; i < arg.length(); i++) {
|
||||
Object obj = arg.getObject(i);
|
||||
|
||||
if (obj instanceof Integer || obj instanceof String || obj instanceof Double)
|
||||
;
|
||||
else if (obj instanceof ConsString)
|
||||
obj = obj.toString();
|
||||
else
|
||||
obj = produceJS(obj);
|
||||
|
||||
traceinitarray.put(i, obj);
|
||||
}
|
||||
currentArrayMap.put(traceinitarray.getArrayId(), traceinitarray);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
* Context.TRACESETGLOBALOBJECTPROTO = new TraceSetGlobalObjectProto() {
|
||||
*
|
||||
* @Override public void trace(int id, int id2,List<Object> keys,List<Object>
|
||||
* values) { System.out.println("[startRecord] set global object proto id=" + id
|
||||
* + " id2=" + id2 + " size=" + keys.size());
|
||||
*
|
||||
*
|
||||
*
|
||||
* TraceInitObject traceinitobject = new TraceInitObject(id,id2); for(int i =
|
||||
* 0;i < keys.size();i++) { System.out.println("i=" + i + " key=" + keys.get(i)
|
||||
* + " value=" + values.get(i)); } currentTraceRecord.record(traceinitobject); }
|
||||
*
|
||||
* };
|
||||
*/
|
||||
}
|
||||
|
||||
public void stopRecordTrace() {
|
||||
Context.TRACESETBEHAVIOR = null;
|
||||
Context.TRACESETUPARRAY = null;
|
||||
Context.TRACESETUPSCRIPTOBJECT = null;
|
||||
// recording = false;
|
||||
}
|
||||
|
||||
public static JS produceJS(Object arg) {
|
||||
if (arg == null) {
|
||||
return new JSNull();
|
||||
} else if (arg instanceof NativeArray) {
|
||||
JSArray arr = new JSArray(((ScriptObject) arg).getObjectID());
|
||||
return arr;
|
||||
} else if (arg instanceof ScriptObject) {
|
||||
JSObject obj = new JSObject(((ScriptObject) arg).getObjectID());
|
||||
return obj;
|
||||
} else if (arg instanceof wrp.jdk.nashorn.internal.runtime.Undefined) {
|
||||
return new JSUndifined();
|
||||
} else {
|
||||
System.out.println("[produceJS] arg encounter new type!" + arg.toString() + " " + arg.getClass());
|
||||
return new JS();
|
||||
}
|
||||
}
|
||||
|
||||
//每次事务开始时初始化
|
||||
public void startNext() {
|
||||
currentTraceRecord = new TraceRecord();
|
||||
currentArrayMap = new LinkedHashMap<Integer,TraceInitArray>();
|
||||
currentMap = new LinkedHashMap<TraceSetIdentifier,TraceSet>();
|
||||
}
|
||||
|
||||
//每次事务结束时记录
|
||||
public void eachFinish() {
|
||||
addSmpSet();
|
||||
currentTraceRecord.record(new TraceDone(ScriptObject.getAllocID()));
|
||||
traceRecords.add(currentTraceRecord);
|
||||
}
|
||||
}
|
||||
334
src/main/java/org/bdware/sc/trace/TraceRecoverUtil.java
Normal file
334
src/main/java/org/bdware/sc/trace/TraceRecoverUtil.java
Normal file
@@ -0,0 +1,334 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import org.bdware.sc.boundry.JavaScriptEntry;
|
||||
import org.bdware.sc.engine.DesktopEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.NashornScriptEngine;
|
||||
import wrp.jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import wrp.jdk.nashorn.internal.objects.Global;
|
||||
import wrp.jdk.nashorn.internal.runtime.Context;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptFunction;
|
||||
import wrp.jdk.nashorn.internal.runtime.ScriptObject;
|
||||
import wrp.jdk.nashorn.internal.scripts.JO;
|
||||
|
||||
import javax.script.Bindings;
|
||||
import javax.script.ScriptContext;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
public class TraceRecoverUtil {
|
||||
DesktopEngine engine;
|
||||
NashornScriptEngine nashornEngine;
|
||||
|
||||
private ArrayList<TraceRecord> traceRecords;
|
||||
|
||||
private int recoverFlag; // 表示当前traceRecords中第i个已经恢复
|
||||
|
||||
// 存储恢复过程中的局部变量
|
||||
private Map<Integer, ScriptObjectMirror> recoverMap;
|
||||
|
||||
public TraceRecoverUtil(DesktopEngine de) {
|
||||
this.engine = de;
|
||||
recoverFlag = -1;
|
||||
nashornEngine = engine.getNashornEngine();
|
||||
}
|
||||
|
||||
public Map<Integer, ScriptObjectMirror> getMap() {
|
||||
return recoverMap;
|
||||
}
|
||||
|
||||
public ArrayList<TraceRecord> getTraceRecords() {
|
||||
if (traceRecords == null) {
|
||||
return null;
|
||||
}
|
||||
return this.traceRecords;
|
||||
}
|
||||
|
||||
public TraceRecord getTraceRecord(int c) {
|
||||
if (traceRecords == null) return null;
|
||||
else if (traceRecords.size() <= c) return null;
|
||||
else return traceRecords.get(c);
|
||||
}
|
||||
|
||||
public String getTraceRecordsContent() {
|
||||
StringBuilder str = new StringBuilder();
|
||||
|
||||
for (int i = 0; i < traceRecords.size(); i++) {
|
||||
str.append("No." + i + "record : \n" + traceRecords.get(i).toString());
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
|
||||
public void setTraceRecords(String fileName) {
|
||||
File file = new File(fileName);
|
||||
ObjectInputStream reader;
|
||||
try {
|
||||
FileInputStream fileout = new FileInputStream(file);
|
||||
GZIPInputStream gzin = new GZIPInputStream(fileout);
|
||||
reader = new ObjectInputStream(gzin);
|
||||
traceRecords = (ArrayList<TraceRecord>) reader.readObject();
|
||||
reader.close();
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void recoverInit() {
|
||||
this.recoverMap = new HashMap();
|
||||
Bindings bindings = nashornEngine.getBindings(ScriptContext.ENGINE_SCOPE);
|
||||
System.out.println(bindings);
|
||||
|
||||
for (String key : bindings.keySet()) {
|
||||
Object obj = bindings.get(key);
|
||||
if (obj instanceof ScriptObjectMirror) initRecoverMap((ScriptObjectMirror) obj);
|
||||
}
|
||||
Context.setGlobal(JavaScriptEntry.getEngineGlobal());
|
||||
}
|
||||
|
||||
public String recoverFromTraceRecord() {
|
||||
System.out.println("[TraceRecoverUtil] recoverFromTraceRecord : ");
|
||||
|
||||
recoverInit();
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != engine.getDesktopGlobal());
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(engine.getDesktopGlobal());
|
||||
}
|
||||
|
||||
for (int i = 0; i < traceRecords.size(); i++) {
|
||||
TraceRecord traceRecord = traceRecords.get(i);
|
||||
System.out.println(traceRecord.toString());
|
||||
|
||||
for (int j = 0; j < traceRecord.length(); j++) {
|
||||
// System.out.println("trace <" + j + ">");
|
||||
|
||||
Trace trace = traceRecord.traces.get(j);
|
||||
|
||||
if (trace instanceof TraceSetup) {
|
||||
recoverSetup((TraceSetup) trace);
|
||||
} else if (trace instanceof TraceSet) {
|
||||
recoverSet((TraceSet) trace);
|
||||
} else if (trace instanceof TraceDone) {
|
||||
// System.out.println("[DesktopEngine] recover TraceDone, before set:" +
|
||||
// ScriptObject.getAllocID()
|
||||
// + " -->" + ((TraceDone) trace).getID());
|
||||
ScriptObject.setAllocID(((TraceDone) trace).getID());
|
||||
} else if (trace instanceof TraceInitArray) {
|
||||
recoverInitArray((TraceInitArray) trace);
|
||||
} else if (trace instanceof TraceInitObject) { // un use
|
||||
recoverInitObject((TraceInitObject) trace);
|
||||
}
|
||||
}
|
||||
|
||||
recoverFlag = i;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
|
||||
return "[recoverFromTraceRecord] recover all";
|
||||
}
|
||||
/*
|
||||
* 通过traceRecord进行恢复 从当前状态恢复到第c次执行之后的状态
|
||||
*/
|
||||
public String recoverFromTraceRecord(int c) {
|
||||
int oldflag = recoverFlag;
|
||||
|
||||
if (recoverFlag < 0) recoverInit();
|
||||
|
||||
if (recoverFlag > c) {
|
||||
System.out.println(
|
||||
"[recoverFromTraceRecord] recoverFlag now is "
|
||||
+ recoverFlag
|
||||
+ " ,can't recover to "
|
||||
+ c
|
||||
+ " !");
|
||||
return "recover from trace failed!";
|
||||
}
|
||||
|
||||
if (c >= traceRecords.size()) {
|
||||
System.out.println(
|
||||
"[recoverFromTraceRecord] traceRecords' size now is "
|
||||
+ traceRecords.size()
|
||||
+ " ,can't recover to "
|
||||
+ c
|
||||
+ " !");
|
||||
return "recover from trace failed!";
|
||||
}
|
||||
|
||||
Global oldGlobal = Context.getGlobal();
|
||||
boolean globalChanged = (oldGlobal != engine.getDesktopGlobal());
|
||||
try {
|
||||
if (globalChanged) {
|
||||
Context.setGlobal(engine.getDesktopGlobal());
|
||||
}
|
||||
|
||||
for (int i = recoverFlag + 1; i <= c; i++) {
|
||||
TraceRecord traceRecord = traceRecords.get(i);
|
||||
|
||||
for (int j = 0; j < traceRecord.length(); j++) {
|
||||
// System.out.println("trace <" + j + ">");
|
||||
|
||||
Trace trace = traceRecord.traces.get(j);
|
||||
|
||||
if (trace instanceof TraceSetup) {
|
||||
recoverSetup((TraceSetup) trace);
|
||||
} else if (trace instanceof TraceSet) {
|
||||
recoverSet((TraceSet) trace);
|
||||
} else if (trace instanceof TraceDone) {
|
||||
// System.out.println("[DesktopEngine] recover TraceDone, before set:" +
|
||||
// ScriptObject.getAllocID()
|
||||
// + " -->" + ((TraceDone) trace).getID());
|
||||
ScriptObject.setAllocID(((TraceDone) trace).getID());
|
||||
} else if (trace instanceof TraceInitArray) {
|
||||
recoverInitArray((TraceInitArray) trace);
|
||||
} else if (trace instanceof TraceInitObject) { // un use
|
||||
recoverInitObject((TraceInitObject) trace);
|
||||
}
|
||||
}
|
||||
|
||||
recoverFlag = i;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
||||
} finally {
|
||||
Context.setGlobal(oldGlobal);
|
||||
}
|
||||
|
||||
recoverFlag = c;
|
||||
|
||||
return "[recoverFromTraceRecord] recover from " + oldflag + " to " + c;
|
||||
}
|
||||
|
||||
public void recoverSetup(TraceSetup trace) {
|
||||
// System.out.println("[recoverSetup]\n" + trace.traceContent());
|
||||
|
||||
ScriptObjectMirror obj = null;
|
||||
int id = -1;
|
||||
|
||||
if (trace.getObj() instanceof JSArray) {
|
||||
id = ((JSArray) trace.getObj()).getObjID();
|
||||
obj =
|
||||
(ScriptObjectMirror)
|
||||
ScriptObjectMirror.wrap(
|
||||
Global.allocate(new int[0]), engine.getDesktopGlobal());
|
||||
obj.setObjectID(id);
|
||||
} else if (trace.getObj() instanceof JSObject) {
|
||||
|
||||
id = ((JSObject) trace.getObj()).getObjID();
|
||||
JO so = new JO(JO.getInitialMap());
|
||||
so.setObjectID(id);
|
||||
obj = (ScriptObjectMirror) ScriptObjectMirror.wrap(so, engine.getDesktopGlobal());
|
||||
|
||||
/*
|
||||
* System.out.println("[recover setup JSObject] : "); id = ((JSObject)
|
||||
* trace.getObj()).getObjID();
|
||||
*
|
||||
* PropertyMap map = PropertyMap.newMap(); for(int i = 0;i <
|
||||
* trace.proLength();i++) { map.addProperty(trace.get(i)); } ScriptObject so =
|
||||
* new JO(map);
|
||||
*
|
||||
*
|
||||
*
|
||||
*
|
||||
* so.setObjectID(id); obj = (ScriptObjectMirror) ScriptObjectMirror.wrap(so,
|
||||
* JavaScriptEntry.getEngineGlobal());
|
||||
*/
|
||||
|
||||
}
|
||||
recoverMap.put(id, obj);
|
||||
}
|
||||
|
||||
public void recoverInitArray(TraceInitArray trace) {
|
||||
// System.out.println("[recoverInitArray]\n" + trace.traceContent());
|
||||
|
||||
for (int i = 0; i < trace.getLength(); i++) {
|
||||
TraceSet trace2 = new TraceSet(trace.getArrayId(), trace.getKey(i), trace.getValue(i));
|
||||
recoverSet(trace2);
|
||||
}
|
||||
}
|
||||
|
||||
public void recoverInitObject(TraceInitObject trace) {
|
||||
// System.out.println("[recoverInitObject]\n" + trace.traceContent());
|
||||
// System.out.println("id=" + trace.getId() + " id2=" + trace.getId2());
|
||||
ScriptObject so = getScriptObjectMirrorById(trace.getId()).getScriptObject();
|
||||
ScriptObject so2 = (getScriptObjectMirrorById(trace.getId2())).getScriptObject();
|
||||
// System.out.println("so=" + so.toString() + " so2=" + so2.toString());
|
||||
so.setGlobalObjectProto(so2);
|
||||
}
|
||||
|
||||
public void recoverSet(TraceSet trace) {
|
||||
// System.out.println("[recoverSet]\n" + trace.traceContent());
|
||||
|
||||
ScriptObjectMirror owner = getScriptObjectMirrorById(trace.getOwner());
|
||||
Object key = trace.getKey();
|
||||
Object value = trace.getValue();
|
||||
|
||||
// 把JS类型转化为ScriptObjectMirror
|
||||
if (value instanceof JSObject)
|
||||
value = getScriptObjectMirrorById(((JSObject) value).getObjID());
|
||||
// 目前JSArray和JSObject一样,可能可以简化
|
||||
else if (value instanceof JSArray)
|
||||
value = getScriptObjectMirrorById(((JSArray) value).getObjID());
|
||||
else if (value instanceof String || value instanceof Integer || value instanceof Double) ;
|
||||
else if (value instanceof JSNull) // 数组trace中可能存在null和Undifined类型,赋值时跳过
|
||||
return;
|
||||
else if (value instanceof JSUndifined) {
|
||||
return;
|
||||
} else System.out.println("[recoverSet] encounter new value type!" + value.toString());
|
||||
|
||||
// 修改ScriptObjectMirror中的setMemeber,使它支持所有类型
|
||||
owner.setMember2(key, value);
|
||||
}
|
||||
|
||||
/*
|
||||
* 将bindings中的变量放入recoverMap 对于函数的scope中的对象以及对象中的对象的情况可以通过递归将所有需要的都放入recoverMap中
|
||||
*/
|
||||
private void initRecoverMap(ScriptObjectMirror obj) {
|
||||
if (obj == null) return;
|
||||
if (recoverMap.containsKey(obj.getObjectID())) return;
|
||||
recoverMap.put(obj.getObjectID(), obj);
|
||||
|
||||
// 全局变量从bindings中获得
|
||||
for (String key : obj.getOwnKeys(true)) {
|
||||
try {
|
||||
Object value = obj.getMember(key);
|
||||
if (value instanceof ScriptObjectMirror) {
|
||||
ScriptObjectMirror svalue = (ScriptObjectMirror) value;
|
||||
initRecoverMap(svalue);
|
||||
// 从函数的Scope中获得
|
||||
if (svalue.isFunction()) {
|
||||
ScriptFunction sf = (ScriptFunction) svalue.getScriptObject();
|
||||
ScriptObject s = sf.getScope();
|
||||
ScriptObjectMirror obj2 =
|
||||
(ScriptObjectMirror)
|
||||
ScriptObjectMirror.wrap(
|
||||
s, JavaScriptEntry.getEngineGlobal());
|
||||
initRecoverMap(obj2);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ScriptObjectMirror getScriptObjectMirrorById(int id) {
|
||||
ScriptObjectMirror so = null;
|
||||
|
||||
// 从recoverMap中获得
|
||||
if (recoverMap.containsKey(id)) return recoverMap.get(id);
|
||||
|
||||
System.out.println("[getScriptObjectMirrorById] can't find the ScriptObjectMirror by id!");
|
||||
return so;
|
||||
}
|
||||
}
|
||||
53
src/main/java/org/bdware/sc/trace/TraceSet.java
Normal file
53
src/main/java/org/bdware/sc/trace/TraceSet.java
Normal file
@@ -0,0 +1,53 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/*
|
||||
* 记录nashorn中setElem和setProp的trace
|
||||
* 自定义对象和数组的set不同
|
||||
*/
|
||||
public class TraceSet extends Trace implements Serializable{
|
||||
int owner; //该对象的id
|
||||
Object key;
|
||||
Object value;
|
||||
|
||||
public TraceSet(int id,Object k,Object v) {
|
||||
owner = id;
|
||||
key = k;
|
||||
value = v;
|
||||
}
|
||||
|
||||
public void setOwner(int owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public void setKey(Object k) {
|
||||
this.key = k;
|
||||
}
|
||||
|
||||
public void setValue(Object v) {
|
||||
this.value = v;
|
||||
}
|
||||
|
||||
public int getOwner() {
|
||||
return this.owner;
|
||||
}
|
||||
|
||||
public Object getKey() {
|
||||
return this.key;
|
||||
}
|
||||
|
||||
public Object getValue() {
|
||||
return this.value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent(){
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceSet]\n");
|
||||
str.append("owner=" + owner + "\n");
|
||||
str.append("key=" + key.getClass() + " " + key.toString() + "\n");
|
||||
str.append("value=" + value.getClass() + " " + value.toString() + "\n");
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
61
src/main/java/org/bdware/sc/trace/TraceSetIdentifier.java
Normal file
61
src/main/java/org/bdware/sc/trace/TraceSetIdentifier.java
Normal file
@@ -0,0 +1,61 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
public class TraceSetIdentifier {
|
||||
int owner;
|
||||
Object key;
|
||||
|
||||
public TraceSetIdentifier(int id,Object k) {
|
||||
this.owner = id;
|
||||
this.key = k;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(obj == null && this == null)
|
||||
return true;
|
||||
else if(obj == null && this != null)
|
||||
return false;
|
||||
else if(obj != null && this == null)
|
||||
return false;
|
||||
|
||||
if(this == obj)
|
||||
return true;
|
||||
|
||||
TraceSetIdentifier obj2 = (TraceSetIdentifier)obj;
|
||||
|
||||
if(this.owner != obj2.owner)
|
||||
return false;
|
||||
|
||||
if(this.key instanceof String && obj2.key instanceof String && obj2.key.equals(this.key))
|
||||
return true;
|
||||
else if(this.key instanceof Double && obj2.key instanceof Double && obj2.key.equals(this.key))
|
||||
return true;
|
||||
else
|
||||
System.out.println("[TraceSetIdentifier] error : encounter new key type : " + this.key.getClass().getName());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
int result = 17,temp = 0;
|
||||
result = 31 * result + owner;
|
||||
|
||||
if(key instanceof String) {
|
||||
String k = (String)key;
|
||||
result = result * 31 + k.hashCode();
|
||||
result = result * 31 + temp;
|
||||
}else if(key instanceof Double) {
|
||||
double t = (Double)key;
|
||||
temp = (int)t;
|
||||
result = result * 31 + temp;
|
||||
}else {
|
||||
System.out.println("[TraceSetIdentifier] error : encounter new key type : " + this.key.getClass().getName());
|
||||
}
|
||||
|
||||
if(result < 0)
|
||||
result = -result;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
54
src/main/java/org/bdware/sc/trace/TraceSetup.java
Normal file
54
src/main/java/org/bdware/sc/trace/TraceSetup.java
Normal file
@@ -0,0 +1,54 @@
|
||||
package org.bdware.sc.trace;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import wrp.jdk.nashorn.internal.runtime.Property;
|
||||
|
||||
/*
|
||||
* 记录nashorn中ScriptObject创建的trace
|
||||
*/
|
||||
public class TraceSetup extends Trace implements Serializable{
|
||||
JSScript obj; //被创建的ScriptObject
|
||||
List<Property> properties;
|
||||
|
||||
public TraceSetup(JSScript o) {
|
||||
this.obj = o;
|
||||
properties = new ArrayList<Property>();
|
||||
}
|
||||
|
||||
public JSScript getObj() {
|
||||
return this.obj;
|
||||
}
|
||||
|
||||
public void add(Property p) {
|
||||
properties.add(p);
|
||||
}
|
||||
|
||||
public Property get(int i) {
|
||||
return properties.get(i);
|
||||
}
|
||||
|
||||
public int proLength() {
|
||||
return properties.size();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String traceContent(){
|
||||
StringBuilder str = new StringBuilder();
|
||||
str.append("[TraceSetup]\n");
|
||||
if(obj instanceof JSObject)
|
||||
str.append(((JSObject)obj).getObjID() + "," + ((JSObject)obj).getClass()+ " " + /*map.toString() +*/ "\n");
|
||||
else if(obj instanceof JSArray)
|
||||
str.append(((JSArray)obj).getObjID() + "," + ((JSArray)obj).getClass() + " " +/* map.toString() + */"\n");
|
||||
|
||||
if(properties.size() > 0) {
|
||||
str.append("properties : " + "\n");
|
||||
for(int i = 0;i < properties.size();i++)
|
||||
str.append(properties.get(i) + "\n");
|
||||
}
|
||||
|
||||
return str.toString();
|
||||
}
|
||||
}
|
||||
8
src/main/resources/log4j.properties
Normal file
8
src/main/resources/log4j.properties
Normal file
@@ -0,0 +1,8 @@
|
||||
### 设置###
|
||||
log4j.rootLogger = debug,stdout
|
||||
|
||||
### 输出信息到控制抬 ###
|
||||
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
|
||||
log4j.appender.stdout.Target = System.out
|
||||
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
|
||||
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{HH:mm:ss.SSS} %m (%F:%L)[%M]%n
|
||||
15
src/main/resources/log4j2.properties
Normal file
15
src/main/resources/log4j2.properties
Normal file
@@ -0,0 +1,15 @@
|
||||
filter.threshold.type=ThresholdFilter
|
||||
filter.threshold.level=debug
|
||||
appender.console.type=Console
|
||||
appender.console.name=STDOUT
|
||||
appender.console.layout.type=PatternLayout
|
||||
appender.console.layout.pattern=%highlight{[%-5p] %d{HH:mm:ss.SSS} %m (%F:%L)[%M]%n}{FATAL=Bright Red,ERROR=Red,WARN=Yellow,INFO=Green,DEBUG=Blue,TRACE=White}
|
||||
appender.rolling.type=File
|
||||
appender.rolling.name=log
|
||||
appender.rolling.append=true
|
||||
appender.rolling.fileName=./log/ct.log
|
||||
appender.rolling.layout.type=PatternLayout
|
||||
appender.rolling.layout.pattern=%d-%m%n
|
||||
rootLogger.level=info
|
||||
rootLogger.appenderRef.stdout.ref=STDOUT
|
||||
rootLogger.appenderRef.log.ref=log
|
||||
10
src/main/resources/org/bdware/sc/engine/mock-min.js
vendored
Normal file
10
src/main/resources/org/bdware/sc/engine/mock-min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user