790 lines
28 KiB
TypeScript
790 lines
28 KiB
TypeScript
/*
|
|
* @project: TERA
|
|
* @version: Development (beta)
|
|
* @license: MIT (not for evil)
|
|
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
|
|
* Web: https://terafoundation.org
|
|
* Twitter: https://twitter.com/terafoundation
|
|
* Telegram: https://t.me/terafoundation
|
|
*/
|
|
import * as crypto from 'crypto'
|
|
import * as http from 'http'
|
|
// import * as net from 'net'
|
|
import * as url from 'url'
|
|
import * as fs from 'fs'
|
|
import * as querystring from 'querystring'
|
|
|
|
global.PROCESS_NAME = "WEB";
|
|
import '../core/constant'
|
|
global.MAX_STAT_PERIOD = 600;
|
|
global.DATA_PATH = global.GetNormalPathString(global.DATA_PATH);
|
|
global.CODE_PATH = global.GetNormalPathString(global.CODE_PATH);
|
|
import "../core/library"
|
|
import "../core/geo"
|
|
import "./child-process"
|
|
global.READ_ONLY_DB = 1;
|
|
global.MAX_STAT_PERIOD = 600;
|
|
var HostNodeList = [];
|
|
var AllNodeList = [];
|
|
var NodeBlockChain = [];
|
|
|
|
process.on('message', function(msg) {
|
|
switch (msg.cmd) {
|
|
case "retcall":
|
|
var F = global.GlobalRunMap[msg.id];
|
|
if (F) {
|
|
delete global.GlobalRunMap[msg.id];
|
|
F(msg.Err, msg.Params);
|
|
}
|
|
break;
|
|
case "Stat":
|
|
global.ADD_TO_STAT(msg.Name, msg.Value);
|
|
break;
|
|
case "NodeList":
|
|
HostNodeList = msg.Value;
|
|
AllNodeList = msg.ValueAll;
|
|
break;
|
|
case "NodeBlockChain":
|
|
NodeBlockChain = msg.Value;
|
|
break;
|
|
case "DappEvent":
|
|
{
|
|
global.AddDappEventToGlobalMap(msg.Data);
|
|
break;
|
|
}
|
|
case "ToLogClient":
|
|
{
|
|
global.ToLogClient0(msg.Str, msg.StrKey, msg.bFinal);
|
|
break;
|
|
}
|
|
case "RetFindTX":
|
|
{
|
|
if (msg.WebID) {
|
|
var F = global.GlobalRunMap[msg.WebID];
|
|
if (F) {
|
|
delete global.GlobalRunMap[msg.WebID];
|
|
F(msg.Result, msg.ResultStr);
|
|
break;
|
|
}
|
|
}
|
|
global.ArrLogClient.push({ text: msg.ResultStr, key: msg.TX, final: msg.bFinal, });
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
var RedirectServer;
|
|
var HostingServer;
|
|
|
|
global.OnExit = function() {
|
|
if (RedirectServer)
|
|
RedirectServer.close();
|
|
if (HostingServer)
|
|
HostingServer.close();
|
|
};
|
|
|
|
if (!global.HTTP_HOSTING_PORT) {
|
|
global.ToLogTrace("global.HTTP_HOSTING_PORT=" + global.HTTP_HOSTING_PORT);
|
|
global.OnExit();
|
|
process.exit();
|
|
}
|
|
var CServerDB = require("../core/db/block-db");
|
|
var KeyPair = crypto.createECDH('secp256k1');
|
|
KeyPair.setPrivateKey(Buffer.from([77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77, 77]));
|
|
global.SERVER = new CServerDB(KeyPair, undefined, undefined, false, true);
|
|
global.HTTP_PORT_NUMBER = 0;
|
|
require("../core/html-server");
|
|
require("../core/transaction-validator");
|
|
global.STAT_MODE = 1;
|
|
setInterval(global.PrepareStatEverySecond, 1000);
|
|
var IndexName = "index.html";
|
|
|
|
if (global.HTTPS_HOSTING_DOMAIN && global.HTTP_HOSTING_PORT === 443) {
|
|
var file_sert = global.GetDataPath("sertif.lst");
|
|
global.CheckCreateDir(global.GetDataPath("tmp"));
|
|
var greenlock = require('greenlock').create({
|
|
version: 'draft-12', server: 'https://acme-v02.api.letsencrypt.org/directory', configDir: global.GetDataPath('tmp'),
|
|
});
|
|
var redir = require('redirect-https')();
|
|
RedirectServer = require('http').createServer(greenlock.middleware(redir));
|
|
RedirectServer.on('error', function(err) {
|
|
global.ToError('RedirectServer: ' + err.code);
|
|
});
|
|
RedirectServer.listen(80);
|
|
var GetNewSert = 1;
|
|
if (fs.existsSync(file_sert)) {
|
|
var certs = global.LoadParams(file_sert, {});
|
|
var Delta = certs.expiresAt - Date.now();
|
|
if (Delta >= 10 * 24 * 3600 * 1000) {
|
|
global.ToLog("USE EXIST SERT. ExpiresAt: " + new Date(certs.expiresAt));
|
|
GetNewSert = 0;
|
|
var tlsOptions = { key: certs.privkey, cert: certs.cert + '\r\n' + certs.chain };
|
|
HostingServer = require('https').createServer(tlsOptions, MainHTTPFunction);
|
|
RunListenServer();
|
|
}
|
|
}
|
|
if (GetNewSert) {
|
|
global.ToLog("Start get new SERT", 0);
|
|
var opts = { domains: [global.HTTPS_HOSTING_DOMAIN], email: 'progr76@gmail.com', agreeTos: true, communityMember: true, };
|
|
greenlock.register(opts).then(function(certs) {
|
|
global.SaveParams(file_sert, certs);
|
|
var tlsOptions = { key: certs.privkey, cert: certs.cert + '\r\n' + certs.chain };
|
|
HostingServer = require('https').createServer(tlsOptions, MainHTTPFunction);
|
|
RunListenServer();
|
|
}, function(err) {
|
|
global.ToError(err);
|
|
});
|
|
}
|
|
} else {
|
|
HostingServer = http.createServer(MainHTTPFunction);
|
|
RunListenServer();
|
|
}
|
|
|
|
function MainHTTPFunction(request, response) {
|
|
if (!request.headers)
|
|
return;
|
|
if (!request.socket || !request.socket.remoteAddress)
|
|
return;
|
|
global.SetSafeResponce(response);
|
|
var DataURL = url.parse(request.url);
|
|
var Params = querystring.parse(DataURL.query);
|
|
var Path = querystring.unescape(DataURL.pathname);
|
|
if (global.STAT_MODE === 2) {
|
|
global.ADD_TO_STAT("HTTP_ALL");
|
|
response.DetailStatName = ":" + Path;
|
|
}
|
|
var Type = request.method;
|
|
if (Type === "POST") {
|
|
let Response = response;
|
|
let postData = "";
|
|
request.addListener("data", function(postDataChunk) {
|
|
if (postData.length <= 12000 && postDataChunk.length <= 12000)
|
|
postData += postDataChunk;
|
|
else {
|
|
var Str = "Error postDataChunk.length=" + postDataChunk.length;
|
|
global.ToLog(Str, 0);
|
|
Response.writeHead(405, { 'Content-Type': 'text/html' });
|
|
Response.end(Str);
|
|
}
|
|
});
|
|
request.addListener("end", function() {
|
|
var Data;
|
|
if (postData && postData.length) {
|
|
try {
|
|
Data = JSON.parse(postData);
|
|
} catch (e) {
|
|
Response.writeHead(405, { 'Content-Type': 'text/html' });
|
|
Response.end("Error data parsing");
|
|
}
|
|
}
|
|
DoCommandNew(request, response, Type, Path, Data);
|
|
});
|
|
} else {
|
|
DoCommandNew(request, response, Type, Path, Params);
|
|
}
|
|
};
|
|
var bWasRun = 0;
|
|
var TimeToRerun = 3000;
|
|
|
|
function RunListenServer() {
|
|
HostingServer.on('error', function(err) {
|
|
if (err.code === 'EADDRINUSE') {
|
|
TimeToRerun = Math.floor(TimeToRerun * 1.1);
|
|
if (TimeToRerun > 1000000 * 1000)
|
|
return;
|
|
global.ToLogClient('Port ' + global.HTTP_HOSTING_PORT + ' in use, retrying...');
|
|
if (HostingServer.Server)
|
|
HostingServer.Server.close();
|
|
if (!bWasRun)
|
|
setTimeout(function() {
|
|
if (!bWasRun)
|
|
RunListenServer();
|
|
}, TimeToRerun);
|
|
return;
|
|
}
|
|
global.ToError("H##6");
|
|
global.ToError(err);
|
|
});
|
|
global.ToLog("Prepare to run WEB-server on port: " + global.HTTP_HOSTING_PORT);
|
|
HostingServer.listen(global.HTTP_HOSTING_PORT, global.LISTEN_IP, function() {
|
|
if (!bWasRun)
|
|
global.ToLog("Run WEB-server on " + global.LISTEN_IP + ":" + global.HTTP_HOSTING_PORT);
|
|
bWasRun = 1;
|
|
});
|
|
};
|
|
var SiteFolder = global.GetNormalPathString("./SITE");
|
|
if (!fs.existsSync(SiteFolder)) {
|
|
IndexName = "web-wallet.html";
|
|
}
|
|
var LangPathMap = {};
|
|
LangPathMap["ru"] = 1;
|
|
LangPathMap["cn"] = 1;
|
|
LangPathMap["de"] = 1;
|
|
LangPathMap["blog"] = 1;
|
|
LangPathMap["docs"] = 1;
|
|
LangPathMap["game"] = 1;
|
|
var WalletFileMap = {};
|
|
WalletFileMap["coinlib.js"] = 1;
|
|
WalletFileMap["client.js"] = 1;
|
|
WalletFileMap["diagram.js"] = 1;
|
|
WalletFileMap["sha3.js"] = 1;
|
|
WalletFileMap["terahashlib.js"] = 1;
|
|
WalletFileMap["wallet-web.js"] = 1;
|
|
WalletFileMap["wallet-lib.js"] = 1;
|
|
WalletFileMap["crypto-client.js"] = 1;
|
|
WalletFileMap["dapp-inner.js"] = 1;
|
|
WalletFileMap["marked.js"] = 1;
|
|
WalletFileMap["highlight.js"] = 1;
|
|
WalletFileMap["highlight-js.js"] = 1;
|
|
WalletFileMap["highlight-html.js"] = 1;
|
|
WalletFileMap["codes.css"] = 1;
|
|
WalletFileMap["sign-lib-min.js"] = 1;
|
|
WalletFileMap["buttons.css"] = 1;
|
|
WalletFileMap["style.css"] = 1;
|
|
WalletFileMap["wallet.css"] = 1;
|
|
WalletFileMap["history.html"] = 1;
|
|
WalletFileMap["blockviewer.html"] = 1;
|
|
WalletFileMap["web-wallet.html"] = 1;
|
|
WalletFileMap["address_book.png"] = 1;
|
|
WalletFileMap["mobile-wallet.html"] = 1;
|
|
WalletFileMap["mobile-wallet.js"] = 1;
|
|
WalletFileMap["mobile-wallet.css"] = 1;
|
|
WalletFileMap["reload.svg"] = 1;
|
|
WalletFileMap["T.svg"] = 1;
|
|
WalletFileMap["B.svg"] = 1;
|
|
WalletFileMap["blank.svg"] = 1;
|
|
WalletFileMap["info.svg"] = 1;
|
|
WalletFileMap["info.svg"] = 1;
|
|
WalletFileMap["check.svg"] = 1;
|
|
WalletFileMap["right-arrow.svg"] = 1;
|
|
WalletFileMap["down-arrow.svg"] = 1;
|
|
WalletFileMap["glass.svg"] = 1;
|
|
WalletFileMap["dapp-edit.html"] = 1;
|
|
WalletFileMap["TeraLogo.svg"] = 1;
|
|
WalletFileMap["mobile-wallet.html"] = "web-wallet.html";
|
|
global.WebApi2 = {};
|
|
let HostingCaller: HostingCaller = {}
|
|
global.HostingCaller = HostingCaller;
|
|
function DoCommandNew(request, response, Type, Path, Params) {
|
|
if (Path.substring(0, 1) === "/")
|
|
Path = Path.substring(1);
|
|
var ArrPath = Path.split('/', 5);
|
|
if (global.AddonCommand) {
|
|
if (!global.AddonCommand(request, response, Type, Path, Params, ArrPath))
|
|
return;
|
|
}
|
|
var Caller = global.HostingCaller;
|
|
var Method = ArrPath[0];
|
|
if (ArrPath[0] === "api") {
|
|
if (ArrPath[1] === "v2") {
|
|
if (!global.USE_HARD_API_V2) {
|
|
response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': "*" });
|
|
response.end(JSON.stringify({ result: 0, text: "You must set const USE_HARD_API_V2:1" }));
|
|
return;
|
|
}
|
|
Caller = global.WebApi2;
|
|
}
|
|
Method = ArrPath[2];
|
|
}
|
|
if (global.STAT_MODE === 2) {
|
|
global.ADD_TO_STAT("HTTP:" + Method);
|
|
response.DetailStatName = ":" + Method;
|
|
}
|
|
var F = Caller[Method];
|
|
if (F) {
|
|
response.writeHead(200, { 'Content-Type': 'text/plain', 'Access-Control-Allow-Origin': "*" });
|
|
var Ret;
|
|
try {
|
|
Ret = F(Params, response, ArrPath);
|
|
} catch (e) {
|
|
Ret = { result: 0, text: e.message, text2: e.stack };
|
|
}
|
|
if (Ret === null)
|
|
return;
|
|
try {
|
|
var Str;
|
|
if (typeof Ret === "object")
|
|
Str = JSON.stringify(Ret);
|
|
else
|
|
Str = Ret;
|
|
response.end(Str);
|
|
} catch (e) {
|
|
global.ToLog("ERR PATH:" + Path);
|
|
global.ToLog(e);
|
|
response.end();
|
|
}
|
|
return;
|
|
}
|
|
Method = Method.toLowerCase();
|
|
if (Method === "dapp" && ArrPath.length === 2)
|
|
Method = "DappTemplateFile";
|
|
switch (Method) {
|
|
case "index.html":
|
|
response.writeHead(301, { "Location": '/' });
|
|
return response.end();
|
|
case "file":
|
|
global.SendBlockFile(response, ArrPath[1], ArrPath[2]);
|
|
break;
|
|
case "DappTemplateFile":
|
|
global.DappTemplateFile(response, ArrPath[1]);
|
|
break;
|
|
case "smart":
|
|
global.DappSmartCodeFile(response, ArrPath[1]);
|
|
break;
|
|
case "client":
|
|
global.DappClientCodeFile(response, ArrPath[1]);
|
|
break;
|
|
default:
|
|
{
|
|
var Name = ArrPath[ArrPath.length - 1];
|
|
if (typeof Name !== "string")
|
|
Name = "ErrorPath";
|
|
else
|
|
if (Name.indexOf("..") >= 0 || Name.indexOf("\\") >= 0 || Name.indexOf("/") >= 0)
|
|
Name = "ErrorFilePath";
|
|
if (Name === "" || LangPathMap[Name])
|
|
Name = IndexName;
|
|
if (Name.indexOf(".") < 0)
|
|
Name += ".html";
|
|
var PrefixPath;
|
|
if (Method === "files") {
|
|
PrefixPath = "../FILES";
|
|
Name = "";
|
|
for (var i = 1; i < ArrPath.length; i++)
|
|
if (ArrPath[i].indexOf("..") === - 1 && ArrPath[i].indexOf("\\") === - 1)
|
|
Name += "/" + ArrPath[i];
|
|
Name = PrefixPath + Name;
|
|
global.SendWebFile(response, Name, Path);
|
|
return;
|
|
} else
|
|
if (LangPathMap[Method]) {
|
|
PrefixPath = "./SITE/" + Method;
|
|
} else {
|
|
var Name2 = WalletFileMap[Name];
|
|
if (!Name2)
|
|
PrefixPath = "./SITE";
|
|
else {
|
|
PrefixPath = "./HTML";
|
|
if (typeof Name2 === "string")
|
|
Name = Name2;
|
|
}
|
|
}
|
|
var type = Path.substr(Path.length - 3, 3);
|
|
switch (type) {
|
|
case ".js":
|
|
Name = PrefixPath + "/JS/" + Name;
|
|
break;
|
|
case "css":
|
|
Name = PrefixPath + "/CSS/" + Name;
|
|
break;
|
|
case "wav":
|
|
case "mp3":
|
|
Name = PrefixPath + "/SOUND/" + Name;
|
|
break;
|
|
case "svg":
|
|
case "png":
|
|
case "gif":
|
|
case "jpg":
|
|
case "ico":
|
|
Name = PrefixPath + "/PIC/" + Name;
|
|
break;
|
|
case "pdf":
|
|
case "zip":
|
|
case "exe":
|
|
case "msi":
|
|
Name = PrefixPath + "/FILES/" + Name;
|
|
break;
|
|
default:
|
|
Name = PrefixPath + "/" + Name;
|
|
break;
|
|
}
|
|
global.SendWebFile(response, Name, "", 1);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
HostingCaller.GetCurrentInfo = function(Params) {
|
|
var MaxNumBlockDB = global.SERVER.GetMaxNumBlockDB();
|
|
var Ret: any = {
|
|
result: 1,
|
|
VersionNum: global.UPDATE_CODE_VERSION_NUM,
|
|
NETWORK: global.NETWORK,
|
|
MaxNumBlockDB: MaxNumBlockDB,
|
|
CurBlockNum: global.GetCurrentBlockNumByTime(),
|
|
MaxAccID: global.DApps.Accounts.GetMaxAccount(),
|
|
MaxDappsID: global.DApps.Smart.GetMaxNum(),
|
|
CurTime: Date.now(),
|
|
DELTA_CURRENT_TIME: global.DELTA_CURRENT_TIME,
|
|
MIN_POWER_POW_TR: global.MIN_POWER_POW_TR,
|
|
FIRST_TIME_BLOCK: global.FIRST_TIME_BLOCK,
|
|
CONSENSUS_PERIOD_TIME: global.CONSENSUS_PERIOD_TIME,
|
|
NEW_SIGN_TIME: global.NEW_SIGN_TIME,
|
|
PRICE_DAO: global.PRICE_DAO(MaxNumBlockDB),
|
|
};
|
|
if (typeof Params === "object" && Params.Diagram == 1) {
|
|
var arrNames = ["MAX:ALL_NODES", "MAX:HASH_RATE_B"];
|
|
Ret.arr = global.GET_STATDIAGRAMS(arrNames);
|
|
}
|
|
if (typeof Params === "object" && Params.BlockChain == 1) {
|
|
Ret.BlockChain = NodeBlockChain;
|
|
}
|
|
if (typeof Params === "object" && Params.ArrLog == 1) {
|
|
var ArrLog = [];
|
|
for (var i = 0; i < global.ArrLogClient.length; i++) {
|
|
var Item = global.ArrLogClient[i];
|
|
if (!Item.final)
|
|
continue;
|
|
ArrLog.push(Item);
|
|
}
|
|
Ret.ArrLog = ArrLog;
|
|
}
|
|
return Ret;
|
|
};
|
|
var MaxCountViewRows = global.HTTP_MAX_COUNT_ROWS;
|
|
HostingCaller.GetAccountList = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
var arr = global.DApps.Accounts.GetRowsAccounts(global.ParseNum(Params.StartNum), global.ParseNum(Params.CountNum));
|
|
return { result: 1, arr: arr };
|
|
};
|
|
HostingCaller.GetAccount = function(id) {
|
|
id = global.ParseNum(id);
|
|
var arr = global.DApps.Accounts.GetRowsAccounts(id, 1);
|
|
return { Item: arr[0], result: 1 };
|
|
};
|
|
HostingCaller.GetBlockList = function(Params, response) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
Params.StartNum = global.ParseNum(Params.StartNum);
|
|
Params.CountNum = global.ParseNum(Params.CountNum);
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
return global.HTTPCaller.GetBlockList(Params, response);
|
|
};
|
|
HostingCaller.GetTransactionList = function(Params, response) {
|
|
Params.Param3 = Params.BlockNum;
|
|
return HostingCaller.GetTransactionAll(Params, response);
|
|
};
|
|
HostingCaller.GetTransactionAll = function(Params, response) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
Params.Param3 = global.ParseNum(Params.Param3);
|
|
Params.StartNum = global.ParseNum(Params.StartNum);
|
|
Params.CountNum = global.ParseNum(Params.CountNum);
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
return global.HTTPCaller.GetTransactionAll(Params, response);
|
|
};
|
|
HostingCaller.GetDappList = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
var arr = global.DApps.Smart.GetRows(global.ParseNum(Params.StartNum), global.ParseNum(Params.CountNum), undefined, Params.Filter, 1);
|
|
return { result: 1, arr: arr };
|
|
};
|
|
HostingCaller.GetNodeList = function(Params) {
|
|
var arr = [];
|
|
var List;
|
|
if (typeof Params === "object" && Params.All)
|
|
List = AllNodeList;
|
|
else
|
|
List = HostNodeList;
|
|
var MaxNodes = 20;
|
|
var len = List.length;
|
|
var UseRandom = 0;
|
|
if (len > MaxNodes) {
|
|
UseRandom = 1;
|
|
len = MaxNodes;
|
|
}
|
|
var Geo = 0;
|
|
if (typeof Params === "object" && Params.Geo)
|
|
Geo = 1;
|
|
var mapWasAdd = {};
|
|
for (var i = 0; i < len; i++) {
|
|
var Item;
|
|
if (UseRandom) {
|
|
var num = global.random(List.length);
|
|
Item = List[num];
|
|
if (mapWasAdd[Item.ip]) {
|
|
continue;
|
|
}
|
|
mapWasAdd[Item.ip] = 1;
|
|
}
|
|
else {
|
|
Item = List[i];
|
|
}
|
|
var Value: any = { ip: Item.ip, port: Item.portweb, };
|
|
if (Geo) {
|
|
if (!Item.Geo)
|
|
global.SetGeoLocation(Item);
|
|
Value.latitude = Item.latitude;
|
|
Value.longitude = Item.longitude;
|
|
Value.name = Item.name;
|
|
Value.port = Item.port;
|
|
}
|
|
arr.push(Value);
|
|
}
|
|
var Result = { result: 1, arr: arr, VersionNum: global.UPDATE_CODE_VERSION_NUM, NETWORK: global.NETWORK, };
|
|
return Result;
|
|
};
|
|
var AccountKeyMap = {};
|
|
var LastMaxNum = 0;
|
|
HostingCaller.GetAccountListByKey = function(Params, aaa, bbb, bRet) {
|
|
if (typeof Params !== "object" || !Params.Key)
|
|
return { result: 0, arr: [] };
|
|
var Accounts = global.DApps.Accounts;
|
|
for (var num = LastMaxNum; true; num++) {
|
|
if (Accounts.IsHole(num))
|
|
continue;
|
|
var Data = Accounts.ReadState(num);
|
|
if (!Data)
|
|
break;
|
|
var StrKey = global.GetHexFromArr(Data.PubKey);
|
|
Data.Next = AccountKeyMap[StrKey];
|
|
AccountKeyMap[StrKey] = Data;
|
|
}
|
|
LastMaxNum = num;
|
|
var arr = [];
|
|
var Item = AccountKeyMap[Params.Key];
|
|
while (Item) {
|
|
var Data = Accounts.ReadState(Item.Num);
|
|
if (!Data)
|
|
continue;
|
|
if (!Data.PubKeyStr)
|
|
Data.PubKeyStr = global.GetHexFromArr(Data.PubKey);
|
|
if (Data.Currency)
|
|
Data.CurrencyObj = global.DApps.Smart.ReadSimple(Data.Currency);
|
|
if (Data.Value.Smart) {
|
|
Data.SmartObj = global.DApps.Smart.ReadSimple(Data.Value.Smart);
|
|
try {
|
|
Data.SmartState = global.BufLib.GetObjectFromBuffer(Data.Value.Data, Data.SmartObj.StateFormat, {});
|
|
if (typeof Data.SmartState === "object")
|
|
Data.SmartState.Num = Item.Num;
|
|
} catch (e) {
|
|
Data.SmartState = {};
|
|
}
|
|
}
|
|
arr.unshift(Data);
|
|
Item = Item.Next;
|
|
if (arr.length >= global.HTTP_MAX_COUNT_ROWS)
|
|
break;
|
|
}
|
|
var Ret = { result: 1, arr: arr };
|
|
if (bRet)
|
|
return Ret;
|
|
var Context = global.GetUserContext(Params);
|
|
var StrInfo = JSON.stringify(Ret);
|
|
if (Params.AllData === "0")
|
|
Params.AllData = 0;
|
|
if (!Params.AllData && Context.PrevAccountList === StrInfo) {
|
|
return { result: 0, cache: 1 };
|
|
}
|
|
Context.PrevAccountList = StrInfo;
|
|
Context.NumAccountList++;
|
|
return StrInfo;
|
|
};
|
|
var CategoryMap = {};
|
|
var CategoryArr = [];
|
|
var CategoryDappMaxNumWas = 0;
|
|
HostingCaller.GetDappCategory = function(Params, response) {
|
|
CheckDappCategoryMap();
|
|
return { result: 1, arr: CategoryArr };
|
|
};
|
|
|
|
function CheckDappCategoryMap() {
|
|
var MaxNumNow = global.DApps.Smart.GetMaxNum();
|
|
if (MaxNumNow !== CategoryDappMaxNumWas) {
|
|
for (var Num = CategoryDappMaxNumWas; Num <= MaxNumNow; Num++) {
|
|
var Item = global.DApps.Smart.ReadSimple(Num);
|
|
for (var n = 1; n <= 3; n++) {
|
|
var Name = "Category" + n;
|
|
var Value = Item[Name];
|
|
if (Value) {
|
|
var DappMap = CategoryMap[Value];
|
|
if (!DappMap) {
|
|
DappMap = {};
|
|
CategoryMap[Value] = DappMap;
|
|
CategoryArr.push(Value);
|
|
}
|
|
DappMap[Num] = 1;
|
|
}
|
|
}
|
|
}
|
|
CategoryDappMaxNumWas = MaxNumNow;
|
|
}
|
|
};
|
|
HostingCaller.SendTransactionHex = function(Params, response) {
|
|
if (typeof Params !== "object" || !Params.Hex)
|
|
return { result: 0, text: "object requre" };
|
|
process.RunRPC("AddTransactionFromWeb", { HexValue: Params.Hex }, function(Err, text) {
|
|
var Result = { result: !Err, text: text };
|
|
var Str = JSON.stringify(Result);
|
|
response.end(Str);
|
|
});
|
|
return null;
|
|
};
|
|
HostingCaller.DappSmartHTMLFile = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
return global.HTTPCaller.DappSmartHTMLFile(Params);
|
|
};
|
|
HostingCaller.DappBlockFile = function(Params, responce) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
return global.HTTPCaller.DappBlockFile(Params, responce);
|
|
};
|
|
HostingCaller.DappInfo = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
var SmartNum = global.ParseNum(Params.Smart);
|
|
process.send({ cmd: "SetSmartEvent", Smart: SmartNum });
|
|
var Context = global.GetUserContext(Params);
|
|
var Ret = global.HTTPCaller.DappInfo(Params, undefined, 1);
|
|
Ret.PubKey = undefined;
|
|
var StrInfo = JSON.stringify(Ret);
|
|
if (!Params.AllData && Context.PrevDappInfo === StrInfo) {
|
|
return { result: 0, cache: 1 };
|
|
}
|
|
Context.PrevDappInfo = StrInfo;
|
|
Context.NumDappInfo++;
|
|
Context.LastTime = Date.now();
|
|
Ret.NumDappInfo = Context.NumDappInfo;
|
|
Ret.CurTime = Date.now();
|
|
Ret.CurBlockNum = global.GetCurrentBlockNumByTime();
|
|
Ret.BlockNumDB = global.SERVER.BlockNumDB;
|
|
Ret.MaxAccID = global.DApps.Accounts.GetMaxAccount();
|
|
Ret.MaxDappsID = global.DApps.Smart.GetMaxNum();
|
|
return Ret;
|
|
};
|
|
HostingCaller.DappWalletList = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
var Ret = HostingCaller.GetAccountListByKey(Params, undefined, undefined, 1);
|
|
var Smart = global.ParseNum(Params.Smart);
|
|
var arr = [];
|
|
for (var i = 0; i < Ret.arr.length; i++) {
|
|
if (Params.AllAccounts || Ret.arr[i].Value.Smart === Smart) {
|
|
arr.push(Ret.arr[i]);
|
|
}
|
|
}
|
|
Ret.arr = arr;
|
|
return Ret;
|
|
};
|
|
global.HTTPCaller.DappWalletList = HostingCaller.DappWalletList;
|
|
HostingCaller.DappAccountList = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
var arr = global.DApps.Accounts.GetRowsAccounts(global.ParseNum(Params.StartNum), global.ParseNum(Params.CountNum), undefined, 1);
|
|
return { arr: arr, result: 1 };
|
|
};
|
|
HostingCaller.DappSmartList = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
var arr = global.DApps.Smart.GetRows(global.ParseNum(Params.StartNum), global.ParseNum(Params.CountNum), undefined, undefined, Params.GetAllData,
|
|
Params.TokenGenerate);
|
|
return { arr: arr, result: 1 };
|
|
};
|
|
HostingCaller.DappBlockList = function(Params, response) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
Params.StartNum = global.ParseNum(Params.StartNum);
|
|
Params.CountNum = global.ParseNum(Params.CountNum);
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
return global.HTTPCaller.DappBlockList(Params, response);
|
|
};
|
|
HostingCaller.DappTransactionList = function(Params, response) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
Params.BlockNum = global.ParseNum(Params.BlockNum);
|
|
Params.StartNum = global.ParseNum(Params.StartNum);
|
|
Params.CountNum = global.ParseNum(Params.CountNum);
|
|
if (Params.CountNum > MaxCountViewRows)
|
|
Params.CountNum = MaxCountViewRows;
|
|
if (!Params.CountNum)
|
|
Params.CountNum = 1;
|
|
return global.HTTPCaller.DappTransactionList(Params, response);
|
|
};
|
|
HostingCaller.DappStaticCall = function(Params, response) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
return global.HTTPCaller.DappStaticCall(Params, response);
|
|
};
|
|
HostingCaller.GetHistoryTransactions = function(Params) {
|
|
if (typeof Params !== "object")
|
|
return { result: 0 };
|
|
return global.HTTPCaller.GetHistoryTransactions(Params);
|
|
};
|
|
HostingCaller.GetSupply = function(Params) {
|
|
var Data = global.DApps.Accounts.ReadState(0);
|
|
if (!Data)
|
|
return "";
|
|
else {
|
|
return "" + (global.TOTAL_SUPPLY_TERA - Data.Value.SumCOIN);
|
|
}
|
|
};
|
|
HostingCaller.GetTotalSupply = function(Params) {
|
|
return "" + global.TOTAL_SUPPLY_TERA;
|
|
};
|
|
setInterval(function() {
|
|
if (global.SERVER)
|
|
global.SERVER.Close();
|
|
global.DApps.Accounts.Close();
|
|
global.DApps.Smart.DBSmart.Close();
|
|
}, 500);
|
|
setInterval(function() {
|
|
var MaxNumBlockDB = global.SERVER.GetMaxNumBlockDB();
|
|
var HASHARATE_BLOCK_LENGTH = 10;
|
|
var arr = global.SERVER.GetStatBlockchain("POWER_BLOCKCHAIN", HASHARATE_BLOCK_LENGTH);
|
|
if (arr.length) {
|
|
var SumPow = 0;
|
|
var Count = 0;
|
|
var Value = 0;
|
|
for (var i = arr.length - HASHARATE_BLOCK_LENGTH; i < arr.length; i++)
|
|
if (arr[i]) {
|
|
Value = arr[i];
|
|
SumPow += Value;
|
|
Count++;
|
|
}
|
|
if (!Count)
|
|
Count = 1;
|
|
var AvgPow = SumPow / Count;
|
|
global.ADD_TO_STAT("MAX:HASH_RATE_B", AvgPow);
|
|
}
|
|
var Count = global.COUNT_BLOCK_PROOF + 16 - 1;
|
|
if (MaxNumBlockDB > Count) {
|
|
var StartNum = MaxNumBlockDB - Count;
|
|
NodeBlockChain = global.SERVER.BlockChainToBuf(StartNum, StartNum, MaxNumBlockDB);
|
|
}
|
|
}, 700);
|
|
require("./api-exchange.js");
|
|
try {
|
|
require("../SITE/JS/web-addon.js");
|
|
} catch (e) {
|
|
}
|
|
global.LoadBlockFromNetwork = function(Params, F) {
|
|
global.ToLog("RUN: LoadBlockFromNetwork:" + Params.BlockNum, 2);
|
|
process.RunRPC("LoadBlockFromNetwork", { BlockNum: Params.BlockNum, F: 1 }, function(Err, Block) {
|
|
global.ToLog("RETURN: LoadBlockFromNetwork: " + Params.BlockNum, 2);
|
|
F(Err, Block);
|
|
});
|
|
};
|