tera/src/core/html-server.ts

1812 lines
64 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
*/
"use strict";
import './crypto-library'
import './log'
import { secp256k1 } from '../core/library'
import * as http from 'http'
import * as url from 'url'
import * as fs from 'fs'
import * as querystring from 'querystring'
import * as crypto from 'crypto';
import { STreeBuffer } from './base';
import { TYPE_TRANSACTION } from '../constant/account';
var BlockTree = new STreeBuffer(300 * 1000, global.CompareItemHashSimple, "number");
var ContenTypeMap = {};
ContenTypeMap["js"] = "application/javascript";
ContenTypeMap["css"] = "text/css";
ContenTypeMap["wav"] = "audio/wav";
ContenTypeMap["mp3"] = "audio/mpeg";
ContenTypeMap["mp4"] = "video/mp4";
ContenTypeMap["ico"] = "image/vnd.microsoft.icon";
ContenTypeMap["png"] = "image/png";
ContenTypeMap["gif"] = "image/gif";
ContenTypeMap["jpg"] = "image/jpeg";
ContenTypeMap["html"] = "text/html";
ContenTypeMap["txt"] = "text/plain";
ContenTypeMap["csv"] = "text/csv";
ContenTypeMap["svg"] = "image/svg+xml";
ContenTypeMap[""] = "application/octet-stream";
ContenTypeMap["zip"] = "application/zip";
ContenTypeMap["pdf"] = "application/pdf";
ContenTypeMap["exe"] = "application/octet-stream";
ContenTypeMap["msi"] = "application/octet-stream";
ContenTypeMap["woff"] = "application/font-woff";
ContenTypeMap[".js"] = "application/javascript";
ContenTypeMap["html"] = "text/html";
ContenTypeMap["psd"] = "application/octet-stream";
global.HTTPCaller = {};
function DoCommand(response, Type, Path, params, remoteAddress) {
var F = global.HTTPCaller[params[0]];
if (F) {
if (Type !== "POST") {
response.end();
return;
}
response.writeHead(200, { 'Content-Type': 'text/plain' });
var Ret = F(params[1], response);
if (Ret === null)
return;
try {
var Str = JSON.stringify(Ret);
response.end(Str);
} catch (e) {
global.ToLog("ERR PATH:" + Path);
global.ToLog(e);
response.end();
}
return;
}
var method = params[0];
method = method.toLowerCase();
if (method === "dapp" && params.length === 2)
method = "DappTemplateFile";
switch (method) {
case "":
SendWebFile(response, "./HTML/wallet.html");
break;
case "file":
SendBlockFile(response, params[1], params[2]);
break;
case "DappTemplateFile":
DappTemplateFile(response, params[1]);
break;
case "smart":
DappSmartCodeFile(response, params[1]);
break;
case "client":
DappClientCodeFile(response, params[1]);
break;
default:
{
if (Path.indexOf(".") === - 1)
global.ToError("Error path:" + Path + " remoteAddress=" + remoteAddress);
var path = params[params.length - 1];
if (typeof path !== "string")
path = "ErrorPath";
else
if (path.indexOf("..") >= 0 || path.indexOf("\\") >= 0 || path.indexOf("/") >= 0)
path = "ErrorFilePath";
if (path.indexOf(".") < 0)
path += ".html";
var type = Path.substr(Path.length - 3, 3);
switch (type) {
case ".js":
path = "./HTML/JS/" + path;
break;
case "css":
path = "./HTML/CSS/" + path;
break;
case "wav":
case "mp3":
path = "./HTML/SOUND/" + path;
break;
case "svg":
case "png":
case "gif":
case "jpg":
case "ico":
path = "./HTML/PIC/" + path;
break;
case "pdf":
case "zip":
case "exe":
case "msi":
path = "./HTML/FILES/" + path;
break;
default:
path = "./HTML/" + path;
break;
}
SendWebFile(response, path, Path);
break;
}
}
};
global.DappTemplateFile = DappTemplateFile;
function DappTemplateFile(response, StrNum) {
var Num = parseInt(StrNum);
if (Num && Num <= global.DApps.Smart.GetMaxNum()) {
var Data = global.DApps.Smart.ReadSmart(Num);
if (Data) {
response.writeHead(200, { 'Content-Type': 'text/html', "X-Frame-Options": "sameorigin" });
var Str = fs.readFileSync("HTML/dapp-frame.html", { encoding: "utf8" });
Str = Str.replace(/#template-number#/g, StrNum);
Str = Str.replace(/DAPP Loading.../g, Data.Name);
Str = Str.replace(/.\/tera.ico/g, "/file/" + Data.IconBlockNum + "/" + Data.IconTrNum);
response.end(Str);
return;
}
}
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end();
};
global.DappSmartCodeFile = DappSmartCodeFile;
function DappSmartCodeFile(response, StrNum) {
var Num = parseInt(StrNum);
if (Num && Num <= global.DApps.Smart.GetMaxNum()) {
var Data = global.DApps.Smart.ReadSmart(Num);
if (Data) {
response.writeHead(200, { 'Content-Type': 'application/javascript' });
response.end(Data.Code);
return;
}
}
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end();
};
global.DappClientCodeFile = DappClientCodeFile;
function DappClientCodeFile(response, StrNum) {
var Num = parseInt(StrNum);
if (Num && Num <= global.DApps.Smart.GetMaxNum()) {
var Data = global.DApps.Smart.ReadSmart(Num);
if (Data) {
response.writeHead(200, { 'Content-Type': "text/plain" });
response.end(Data.HTML);
return;
}
}
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end();
};
global.HTTPCaller.DappSmartHTMLFile = function(Params) {
var Data = global.DApps.Smart.ReadSmart(global.ParseNum(Params.Smart));
if (Data) {
if (global.DEV_MODE && Params.DebugPath) {
global.ToLog("Load: " + Params.DebugPath);
Data.HTML = fs.readFileSync(Params.DebugPath, { encoding: "utf8" });
}
return { result: 1, Body: Data.HTML };
}
return { result: 0 };
};
global.SendBlockFile = SendBlockFile;
function SendBlockFile(response, BlockNum, TrNum) {
BlockNum = parseInt(BlockNum);
TrNum = parseInt(TrNum);
if (BlockNum && BlockNum <= global.SERVER.GetMaxNumBlockDB() && TrNum <= global.MAX_TRANSACTION_COUNT) {
var Block = global.SERVER.ReadBlockDB(BlockNum);
if (Block && Block.arrContent) {
SendToResponceFile(response, Block, TrNum);
return;
} else {
if (!Block || !Block.TrDataPos) {
global.LoadBlockFromNetwork({ BlockNum: BlockNum }, function(Err, Block) {
if (Err) {
SendToResponce404(response);
} else {
SendToResponceFile(response, Block, TrNum);
}
});
return;
}
}
}
SendToResponce404(response);
};
function SendToResponceFile(response, Block, TrNum) {
var Body = Block.arrContent[TrNum];
if (Body && Body.data)
Body = Body.data;
if (Body && Body[0] === TYPE_TRANSACTION.TYPE_TRANSACTION_FILE) {
var TR = global.DApps.File.GetObjectTransaction(Body);
if (TR.ContentType.toLowerCase().indexOf("html") >= 0)
response.writeHead(200, { 'Content-Type': "text/plain" });
else
response.writeHead(200, { 'Content-Type': TR.ContentType });
response.end(TR.Data);
} else {
SendToResponce404(response);
}
};
function SendToResponce404(response) {
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end();
};
global.HTTPCaller.DappBlockFile = function(Params, response) {
Params.BlockNum = global.ParseNum(Params.BlockNum);
Params.TrNum = global.ParseNum(Params.TrNum);
if (!Params.TrNum)
Params.TrNum = 0;
if (Params.BlockNum && Params.BlockNum <= global.SERVER.GetMaxNumBlockDB() && Params.TrNum <= global.MAX_TRANSACTION_COUNT) {
var Block = global.SERVER.ReadBlockDB(Params.BlockNum);
if (Block && Block.arrContent) {
SendToResponceDappFile(response, Block, Params.TrNum);
return null;
} else {
if (!Block || !Block.TrDataPos) {
global.LoadBlockFromNetwork(Params, function(Err, Block) {
if (Err) {
SendToResponceResult0(response);
} else {
SendToResponceDappFile(response, Block, Params.TrNum);
}
});
return null;
}
}
}
return { result: 0 };
};
function SendToResponceDappFile(response, Block, TrNum) {
var Result: any = { result: 0 };
var Body = Block.arrContent[TrNum];
if (Body) {
var Type = Body[0];
if (Type === TYPE_TRANSACTION.TYPE_TRANSACTION_FILE) {
var TR = global.DApps.File.GetObjectTransaction(Body);
Result = { result: 1, Type: Type, ContentType: TR.ContentType, Name: TR.Name, Body: TR.Data.toString('utf8') };
} else {
var App = global.DAppByType[Type];
if (App) {
Body = JSON.parse(App.GetScriptTransaction(Body));
}
Result = { result: 1, Type: Type, Body: Body };
}
}
var Str = JSON.stringify(Result);
response.end(Str);
};
function SendToResponceResult0(response) {
if (response)
response.end("{\"result\":0}");
};
var glBlock0;
global.HTTPCaller.DappStaticCall = function(Params, response) {
global.DApps.Accounts.BeginBlock();
global.DApps.Accounts.BeginTransaction();
global.TickCounter = 100000;
var Account = global.DApps.Accounts.ReadStateTR(global.ParseNum(Params.Account));
if (!Account) {
return { result: 0, RetValue: "Error account Num: " + Params.Account };
}
if (!glBlock0)
glBlock0 = global.SERVER.ReadBlockHeaderDB(0);
var RetValue;
try {
RetValue = global.RunSmartMethod(glBlock0, Account.Value.Smart, Account, 0, 0, undefined, Params.MethodName, Params.Params, 1);
} catch (e) {
return { result: 0, RetValue: "" + e };
}
var Str = JSON.stringify({ result: 1, RetValue: RetValue });
if (Str.length > 16000) {
return { result: 0, RetValue: "Error result length (more 16000)" };
}
response.end(Str);
return null;
};
global.HTTPCaller.DappInfo = function(Params, responce, ObjectOnly) {
var SmartNum = global.ParseNum(Params.Smart);
if (global.TX_PROCESS && global.TX_PROCESS.Worker)
global.TX_PROCESS.Worker.send({ cmd: "SetSmartEvent", Smart: SmartNum });
var Account;
var Smart = global.DApps.Smart.ReadSimple(SmartNum);
if (Smart) {
delete Smart.HTML;
delete Smart.Code;
Account = global.DApps.Accounts.ReadState(Smart.Account);
try {
Account.SmartState = global.BufLib.GetObjectFromBuffer(Account.Value.Data, Smart.StateFormat, {});
if (typeof Account.SmartState === "object")
Account.SmartState.Num = Account.Num;
}
catch (e) {
if (!Account)
Account = {};
Account.SmartState = {};
}
}
DeleteOldEvents(SmartNum);
var Context = GetUserContext(Params);
var EArr = GetEventArray(SmartNum, Context);
var WLData = global.HTTPCaller.DappWalletList(Params);
var ArrLog = [];
for (var i = 0; i < global.ArrLogClient.length; i++) {
var Item = global.ArrLogClient[i];
if (!Item.final)
continue;
ArrLog.push(Item);
}
var Ret: any = {
result: 1, 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, PRICE_DAO: global.PRICE_DAO(global.SERVER.BlockNumDB), NEW_SIGN_TIME: global.NEW_SIGN_TIME, Smart: Smart,
Account: Account, ArrWallet: WLData.arr, ArrEvent: EArr, ArrLog: ArrLog,
};
if (global.WALLET) {
Ret.WalletIsOpen = (global.WALLET.WalletOpen !== false);
Ret.WalletCanSign = (global.WALLET.WalletOpen !== false && global.WALLET.KeyPair.WasInit);
Ret.PubKey = global.WALLET.KeyPair.PubKeyStr;
}
if (!ObjectOnly) {
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;
};
global.HTTPCaller.DappWalletList = function(Params) {
var arr0 = global.DApps.Accounts.GetWalletAccountsByMap(global.WALLET.AccountMap);
var arr = [];
for (var i = 0; i < arr0.length; i++) {
if (Params.AllAccounts || arr0[i].Value.Smart === Params.Smart) {
arr.push(arr0[i]);
}
}
var Ret: any = { result: 1, arr: arr, };
return Ret;
};
global.HTTPCaller.DappAccountList = function(Params) {
var arr = global.DApps.Accounts.GetRowsAccounts(Params.StartNum, Params.CountNum, undefined, 1);
return { arr: arr, result: 1 };
};
global.HTTPCaller.DappSmartList = function(Params) {
var arr = global.DApps.Smart.GetRows(Params.StartNum, Params.CountNum, undefined, undefined, Params.GetAllData, Params.TokenGenerate);
return { arr: arr, result: 1 };
};
global.HTTPCaller.DappBlockList = function(Params, response) {
Params.Filter = undefined;
return global.HTTPCaller.GetBlockList(Params, response, 1);
};
global.HTTPCaller.DappTransactionList = function(Params, response) {
Params.Filter = undefined;
Params.Param3 = Params.BlockNum;
return global.HTTPCaller.GetTransactionAll(Params, response);
};
var sessionid = global.GetHexFromAddres(crypto.randomBytes(20));
global.HTTPCaller.RestartNode = function(Params) {
global.RestartNode();
return { result: 1 };
};
global.HTTPCaller.ToLogServer = function(Str) {
global.ToLogClient(Str);
return { result: 1 };
};
global.HTTPCaller.FindMyAccounts = function(Params) {
global.WALLET.FindMyAccounts(1);
return { result: 1 };
};
global.HTTPCaller.GetAccount = function(id) {
id = parseInt(id);
var arr = global.DApps.Accounts.GetRowsAccounts(id, 1);
return { Item: arr[0], result: 1 };
};
global.HTTPCaller.GetAccountList = function(Params) {
if (!Params.CountNum)
Params.CountNum = 1;
var arr = global.DApps.Accounts.GetRowsAccounts(Params.StartNum, Params.CountNum, Params.Filter);
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetDappList = function(Params) {
if (!Params.CountNum)
Params.CountNum = 1;
var arr = global.DApps.Smart.GetRows(Params.StartNum, Params.CountNum, Params.Filter, Params.Filter2, 1);
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetBlockList = function(Params, response, bOnlyNum) {
if (!Params.CountNum)
Params.CountNum = 1;
if (Params.StartNum < global.SERVER.BlockNumDBMin) {
let CountWait = 0;
var WasWait = 0;
for (var BlockNum = Params.StartNum; BlockNum < Params.StartNum + Params.CountNum; BlockNum++) {
var Block = global.SERVER.ReadBlockHeaderDB(BlockNum);
if (!Block) {
CountWait++;
WasWait = 1;
global.LoadBlockFromNetwork({ BlockNum: BlockNum }, function(Err, Block) {
CountWait--;
if (CountWait === 0) {
var arr = global.SERVER.GetRows(Params.StartNum, Params.CountNum, Params.Filter);
var Result: any = { arr: arr, result: 1 };
response.end(JSON.stringify(Result));
}
});
}
}
if (WasWait)
return null;
}
var arr = global.SERVER.GetRows(Params.StartNum, Params.CountNum, Params.Filter, !bOnlyNum);
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetTransactionAll = function(Params, response) {
if (!Params.CountNum)
Params.CountNum = 1;
var BlockNum = Params.Param3;
if (BlockNum < global.SERVER.BlockNumDBMin) {
var Block = global.SERVER.ReadBlockHeaderDB(BlockNum);
if (!Block) {
global.LoadBlockFromNetwork({ BlockNum: BlockNum }, function(Err, Block) {
var Result;
if (Err) {
Result = { arr: [], result: 0 };
}
else {
var arr = global.SERVER.GetTrRows(Block.BlockNum, Params.StartNum, Params.CountNum, Params.Filter);
Result = { arr: arr, result: 1 };
}
var Str = JSON.stringify(Result);
response.end(Str);
});
return null;
}
}
var arr = global.SERVER.GetTrRows(BlockNum, Params.StartNum, Params.CountNum, Params.Filter);
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetActList = function(Params) {
var arr = global.DApps.Accounts.GetActList(Params.StartNum, Params.CountNum, Params.Filter);
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetHashList = function(Params) {
var arr = global.DApps.Accounts.DBAccountsHash.GetRows(Params.StartNum, Params.CountNum, Params.Filter);
for (var i = 0; i < arr.length; i++) {
var item = arr[i];
item.BlockNum = item.Num * global.PERIOD_ACCOUNT_HASH;
item.Hash100 = [];
if (item.BlockNum % 100 === 0) {
var Data = global.SERVER.DBHeader100.Read(item.BlockNum / 100);
if (Data)
item.Hash100 = Data.Hash100;
}
}
return { arr: arr, result: 1 };
};
global.HTTPCaller.GetHistoryAct = function(Params) {
var arr = global.WALLET.GetHistory(Params.StartNum, Params.CountNum, Params.Filter);
return { arr: arr, result: 1 };
};
var LastTimeGetHashRate = 0;
var LastHashRate = 0;
var HashRateOneSec = 0;
global.HTTPCaller.GetWalletInfo = function(Params) {
var Constants = {};
for (var i = 0; i < global.CONST_NAME_ARR.length; i++) {
var key = global.CONST_NAME_ARR[i];
Constants[key] = global[key];
}
var MaxHistory = 0;
var Delta = Date.now() - LastTimeGetHashRate;
if (Delta >= 1000) {
if (Delta < 1100)
HashRateOneSec = global.HASH_RATE - LastHashRate;
LastHashRate = global.HASH_RATE;
LastTimeGetHashRate = Date.now();
}
var StateTX = global.DApps.Accounts.DBStateTX.Read(0);
var TXBlockNum = 0;
if (StateTX)
TXBlockNum = StateTX.BlockNum;
var Ret: any = {
result: 1,
WalletOpen: global.WALLET.WalletOpen,
WalletIsOpen: (global.WALLET.WalletOpen !== false),
WalletCanSign: (global.WALLET.WalletOpen !== false && global.WALLET.KeyPair.WasInit),
CODE_VERSION: global.CODE_VERSION,
MAX_TRANSACTION_LIMIT: global.MAX_TRANSACTION_LIMIT,
VersionNum: global.UPDATE_CODE_VERSION_NUM,
RelayMode: global.SERVER.RelayMode,
BlockNumDB: global.SERVER.BlockNumDB,
CurBlockNum: global.GetCurrentBlockNumByTime(),
CurTime: Date.now(),
IsDevelopAccount: global.IsDeveloperAccount(global.WALLET.PubKeyArr),
AccountMap: global.WALLET.AccountMap,
ArrLog: global.ArrLogClient,
MaxAccID: global.DApps.Accounts.GetMaxAccount(),
MaxActNum: global.DApps.Accounts.GetActsMaxNum(),
MaxDappsID: global.DApps.Smart.GetMaxNum(),
NeedRestart: global.NeedRestart,
ip: global.SERVER.ip,
port: global.SERVER.port,
NET_WORK_MODE: global.NET_WORK_MODE,
INTERNET_IP_FROM_STUN: global.INTERNET_IP_FROM_STUN,
HistoryMaxNum: MaxHistory,
DELTA_CURRENT_TIME: global.DELTA_CURRENT_TIME,
FIRST_TIME_BLOCK: global.FIRST_TIME_BLOCK,
CONSENSUS_PERIOD_TIME: global.CONSENSUS_PERIOD_TIME,
NEW_SIGN_TIME: global.NEW_SIGN_TIME,
DATA_PATH: (global.DATA_PATH.substr(1, 1) === ":" ? global.DATA_PATH : global.GetNormalPathString(process.cwd() + "/" + global.DATA_PATH)),
NodeAddrStr: global.SERVER.addrStr,
STAT_MODE: global.STAT_MODE,
HTTPPort: global.HTTP_PORT_NUMBER,
HTTPPassword: global.HTTP_PORT_PASSWORD,
CONSTANTS: Constants,
CheckPointBlockNum: global.CHECK_POINT.BlockNum,
MiningAccount: global.GENERATE_BLOCK_ACCOUNT,
CountMiningCPU: global.GetCountMiningCPU(),
CountRunCPU: global.ArrMiningWrk.length,
MiningPaused: global.MiningPaused,
HashRate: HashRateOneSec,
MIN_POWER_POW_TR: global.MIN_POWER_POW_TR,
PRICE_DAO: global.PRICE_DAO(global.SERVER.BlockNumDB),
NWMODE: global.NWMODE,
PERIOD_ACCOUNT_HASH: global.PERIOD_ACCOUNT_HASH,
MAX_ACCOUNT_HASH: global.DApps.Accounts.DBAccountsHash.GetMaxNum(),
TXBlockNum: TXBlockNum,
SpeedSignLib: global.SpeedSignLib,
};
if (Params.Account)
Ret.PrivateKey = global.GetHexFromArr(global.WALLET.GetPrivateKey(global.WALLET.AccountMap[Params.Account]));
else
Ret.PrivateKey = global.GetHexFromArr(global.WALLET.GetPrivateKey());
Ret.PublicKey = global.WALLET.KeyPair.PubKeyStr;
return Ret;
};
global.HTTPCaller.GetCurrentInfo = global.HTTPCaller.GetWalletInfo;
global.HTTPCaller.TestSignLib = function() {
global.TestSignLib();
};
global.HTTPCaller.GetWalletAccounts = function() {
var Ret: any = { result: 1, arr: global.DApps.Accounts.GetWalletAccountsByMap(global.WALLET.AccountMap), };
Ret.PrivateKey = global.WALLET.KeyPair.PrivKeyStr;
Ret.PublicKey = global.WALLET.KeyPair.PubKeyStr;
return Ret;
};
global.HTTPCaller.SetWalletKey = function(PrivateKeyStr) {
global.WALLET.SetPrivateKey(PrivateKeyStr, true);
return { result: 1 };
};
global.HTTPCaller.SetWalletPasswordNew = function(Password) {
global.WALLET.SetPasswordNew(Password);
return { result: 1 };
};
global.HTTPCaller.OpenWallet = function(Password) {
var res = global.WALLET.OpenWallet(Password);
return { result: res };
};
global.HTTPCaller.CloseWallet = function() {
var res = global.WALLET.CloseWallet();
return { result: res };
};
global.HTTPCaller.GetSignTransaction = function(TR) {
var Sign = global.WALLET.GetSignTransaction(TR);
return { Sign: Sign, result: 1 };
};
global.HTTPCaller.GetSignFromHEX = function(Params) {
var Arr = global.GetArrFromHex(Params.Hex);
var Sign;
if (Params.Account)
Sign = global.WALLET.GetSignFromArr(Arr, global.WALLET.AccountMap[Params.Account]);
else
Sign = global.WALLET.GetSignFromArr(Arr);
return { Sign: Sign, result: 1 };
};
global.HTTPCaller.SendTransactionHex = function(Params) {
var body = global.GetArrFromHex(Params.Hex);
var Result: any = { result: 1 };
var Res = global.SERVER.AddTransactionOwn({ body: body, ToAll: 1 });
Result.sessionid = sessionid;
Result.text = global.AddTrMap[Res];
var final = false;
if (Res <= 0 && Res !== - 3)
final = true;
global.ToLogClient("Send: " + Result.text, global.GetHexFromArr(global.sha3(body)), final);
return Result;
};
global.HTTPCaller.SendDirectCode = function(Params, response) {
var Result;
if (Params.TX || Params.WEB || Params.ST) {
var RunProcess;
if (Params.TX)
RunProcess = global.TX_PROCESS;
if (Params.WEB)
RunProcess = global.WEB_PROCESS;
if (Params.ST)
RunProcess = global.STATIC_PROCESS;
if (RunProcess && RunProcess.RunRPC) {
RunProcess.RunRPC("EvalCode", Params.Code, function(Err, Ret) {
Result = { result: !Err, sessionid: sessionid, text: Ret, };
var Str = JSON.stringify(Result);
response.end(Str);
});
return null;
}
else {
Result = "No process for send call";
}
}
else {
try {
var ret = eval(Params.Code);
Result = JSON.stringify(ret, undefined, 4);
}
catch (e) {
Result = "" + e;
}
}
var Struct = { result: 1, sessionid: sessionid, text: Result };
return Struct;
};
global.HTTPCaller.SetMining = function(MiningAccount) {
global.WALLET.SetMiningAccount(parseInt(MiningAccount));
return { result: 1 };
};
function CheckCorrectDevKey() {
if (global.WALLET.WalletOpen === false) {
var StrErr = "Not open wallet";
global.ToLogClient(StrErr);
return { result: 0, text: StrErr };
}
if (!global.IsDeveloperAccount(global.WALLET.PubKeyArr)) {
var StrErr = "Not developer key";
global.ToLogClient(StrErr);
return { result: 0, text: StrErr };
}
return true;
};
global.HTTPCaller.SendECode = function(Param) {
var Ret = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (Param.All) {
global.SERVER.ConnectToAll();
var arr = global.SERVER.GetActualNodes();
for (var i = 0; i < arr.length; i++) {
var Node = arr[i];
global.SERVER.SendECode(Param, Node);
}
return { result: 1, text: "Sent to " + arr.length + " nodes" };
}
var Node = global.FindNodeByAddr(Param.Addr, 1);
if (Node === undefined)
return { result: 0, text: "Node not found" };
if (Node === false)
return { result: 0, text: "Node not active - reconnect" };
global.SERVER.SendECode(Param, Node);
return { result: 1, text: "Send" };
};
global.HTTPCaller.SetCheckPoint = function(BlockNum) {
var Ret = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (!BlockNum)
BlockNum = global.SERVER.BlockNumDB;
else
BlockNum = parseInt(BlockNum);
if (SetCheckPointOnBlock(BlockNum))
return { result: 1, text: "Set check point on BlockNum=" + BlockNum };
else
return { result: 0, text: "Error on check point BlockNum=" + BlockNum };
};
function SetCheckPointOnBlock(BlockNum) {
if (global.WALLET.WalletOpen === false)
return 0;
var Block = global.SERVER.ReadBlockHeaderDB(BlockNum);
if (!Block)
return 0;
var SignArr = global.arr2(Block.Hash, global.GetArrFromValue(Block.BlockNum));
var Sign = secp256k1.sign(global.SHA3BUF(SignArr, Block.BlockNum), global.WALLET.KeyPair.getPrivateKey('')).signature;
global.CHECK_POINT = { BlockNum: BlockNum, Hash: Block.Hash, Sign: Sign };
global.SERVER.ResetNextPingAllNode();
return 1;
};
global.SetCheckPointOnBlock = SetCheckPointOnBlock;
var idSetTimeSetCheckPoint;
global.HTTPCaller.SetAutoCheckPoint = function(Param) {
var Ret = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (idSetTimeSetCheckPoint)
clearInterval(idSetTimeSetCheckPoint);
idSetTimeSetCheckPoint = undefined;
if (Param.Set)
idSetTimeSetCheckPoint = setInterval(RunSetCheckPoint, Param.Period * 1000);
return { result: 1, text: "AutoCheck: " + Param.Set + " each " + Param.Period + " sec" };
};
var SumCheckPow = 0;
var CountCheckPow = 0;
function RunSetCheckPoint() {
if (!global.SERVER.BlockNumDB)
return;
if (global.SERVER.BlockNumDB < 2100000)
return;
var Delta = global.GetCurrentBlockNumByTime() - global.SERVER.BlockNumDB;
if (Delta > 16)
return;
var BlockNum = global.SERVER.BlockNumDB - global.CheckPointDelta;
var Block = global.SERVER.ReadBlockHeaderDB(BlockNum);
if (Block) {
var Power = global.GetPowPower(Block.PowHash);
if (Power < 30) {
global.ToLog("CANNOT SET CHECK POINT Power=" + Power + " BlockNum=" + BlockNum);
return;
}
CountCheckPow++;
SumCheckPow += Power;
var AvgPow = SumCheckPow / CountCheckPow;
if (CountCheckPow > 10) {
if (Power < AvgPow - 2) {
global.ToLog("**************** CANNOT SET CHECK POINT Power=" + Power + "/" + AvgPow + " BlockNum=" + BlockNum);
return;
}
}
SetCheckPointOnBlock(BlockNum);
global.ToLog("SET CHECK POINT Power=" + Power + "/" + AvgPow + " BlockNum=" + BlockNum);
}
};
global.HTTPCaller.SetNewCodeVersion = function(Data) {
var Ret: any = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
var Ret = global.SERVER.SetNewCodeVersion(Data, global.WALLET.KeyPair.getPrivateKey(''));
global.SERVER.ResetNextPingAllNode();
return { result: 1, text: Ret };
};
global.HTTPCaller.SetCheckNetConstant = function(Data) {
var Ret: any = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (!Data) {
global.ToLogClient("Data not set");
return { result: 0, text: "Data not set" };
}
Data.Num = global.GetCurrentBlockNumByTime();
Data.BlockNum = global.GetCurrentBlockNumByTime() + 10;
var SignArr = global.SERVER.GetSignCheckNetConstant(Data);
Data.Sign = secp256k1.sign(global.SHA3BUF(SignArr), global.WALLET.KeyPair.getPrivateKey('')).signature;
global.SERVER.CheckNetConstant({ NetConstant: Data }, { addrStr: "local" });
global.SERVER.ResetNextPingAllNode();
return { result: 1, text: "Set NET_CONSTANT BlockNum=" + Data.BlockNum };
};
global.HTTPCaller.SetCheckDeltaTime = function(Data) {
var Ret = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (!Data || !Data.Num) {
global.ToLogClient("Num not set");
return { result: 0 };
}
var SignArr = global.SERVER.GetSignCheckDeltaTime(Data);
Data.Sign = secp256k1.sign(global.SHA3BUF(SignArr), global.WALLET.KeyPair.getPrivateKey('')).signature;
global.CHECK_DELTA_TIME = Data;
global.SERVER.ResetNextPingAllNode();
return { result: 1, text: "Set check time Num=" + Data.Num };
};
var idAutoCorrTime;
global.HTTPCaller.SetAutoCorrTime = function(bSet) {
var Ret = CheckCorrectDevKey();
if (Ret !== true)
return Ret;
if (idAutoCorrTime)
clearInterval(idAutoCorrTime);
idAutoCorrTime = undefined;
if (bSet)
idAutoCorrTime = setInterval(RunAutoCorrTime, 1000);
return { result: 1, text: "Auto correct: " + bSet };
};
var StartCheckTimeNum = 0;
function RunAutoCorrTime() {
if (global.WALLET.WalletOpen === false)
return;
if (global.GetCurrentBlockNumByTime() > StartCheckTimeNum && Math.abs(global.DELTA_CURRENT_TIME) >= 120) {
var AutoDelta = - Math.trunc(global.DELTA_CURRENT_TIME);
var Data: any = { Num: global.GetCurrentBlockNumByTime(), bUse: 1, bAddTime: 1 };
if (AutoDelta < 0) {
AutoDelta = - AutoDelta;
Data.bAddTime = 0;
}
Data.DeltaTime = 40;
Data.StartBlockNum = Data.Num + 5;
Data.EndBlockNum = Data.StartBlockNum + Math.trunc(AutoDelta / Data.DeltaTime);
var SignArr = global.SERVER.GetSignCheckDeltaTime(Data);
Data.Sign = secp256k1.sign(global.SHA3BUF(SignArr), global.WALLET.KeyPair.getPrivateKey('')).signature;
global.CHECK_DELTA_TIME = Data;
global.SERVER.ResetNextPingAllNode();
StartCheckTimeNum = Data.EndBlockNum + 1;
global.ToLog("Auto corr time Num:" + Data.Num + " AutoDelta=" + AutoDelta);
}
};
global.HTTPCaller.SaveConstant = function(SetObj) {
var WasUpdate = global.USE_AUTO_UPDATE;
for (var key in SetObj) {
global[key] = SetObj[key];
}
global.SAVE_CONST(true);
global.SERVER.DO_CONSTANT();
if (!WasUpdate && global.USE_AUTO_UPDATE && global.CODE_VERSION.VersionNum && global.UPDATE_CODE_VERSION_NUM < global.CODE_VERSION.VersionNum) {
global.SERVER.UseCode(global.CODE_VERSION.VersionNum, true);
}
if (SetObj.DoRestartNode)
global.RestartNode();
else {
if (SetObj.DoMining)
global.RunStopPOWProcess();
}
return { result: 1 };
};
global.HTTPCaller.SetHTTPParams = function(SetObj) {
global.HTTP_PORT_NUMBER = SetObj.HTTPPort;
global.HTTP_PORT_PASSWORD = SetObj.HTTPPassword;
global.SAVE_CONST(true);
if (SetObj.DoRestartNode)
global.RestartNode();
return { result: 1 };
};
global.HTTPCaller.SetNetMode = function(SetObj) {
if (!global.NET_WORK_MODE)
global.NET_WORK_MODE = {};
for (var key in SetObj) {
global.NET_WORK_MODE[key] = SetObj[key];
}
if (global.NET_WORK_MODE) {
global.START_IP = global.NET_WORK_MODE.ip;
global.START_PORT_NUMBER = global.NET_WORK_MODE.port;
}
global.SAVE_CONST(true);
if (SetObj.DoRestartNode)
global.RestartNode();
return { result: 1 };
};
global.HTTPCaller.GetAccountKey = function(Num) {
var Result: any = {};
Result.result = 0;
var KeyPair = global.WALLET.GetAccountKey(Num);
if (KeyPair) {
Result.result = 1;
Result.PubKeyStr = global.GetHexFromArr(KeyPair.getPublicKey('', 'compressed'));
}
return Result;
};
global.HTTPCaller.GetHotArray = function(Param) {
var ArrTree = global.SERVER.GetTransferTree();
if (!ArrTree)
return { result: 0 };
for (var Level = 0; Level < ArrTree.length; Level++) {
var arr = ArrTree[Level];
if (arr)
for (var n = 0; n < arr.length; n++) {
arr[n].GetTiming = 0;
}
}
var BlockCounts = 0;
if (Param && Param.CountBlock)
for (var i = global.SERVER.CurrentBlockNum - Param.CountBlock; i <= global.SERVER.CurrentBlockNum - Param.CountBlock; i++) {
var Block = global.SERVER.GetBlock(i);
if (!Block || !Block.Active || !Block.LevelsTransfer) {
continue;
}
BlockCounts++;
for (var n = 0; n < Block.LevelsTransfer.length; n++) {
var Transfer = Block.LevelsTransfer[n];
for (var Addr in Transfer.TransferNodes) {
var Item = Transfer.TransferNodes[Addr];
Item.Node.GetTiming += Item.GetTiming;
}
}
}
for (var Level = 0; Level < ArrTree.length; Level++) {
var arr = ArrTree[Level];
if (!arr)
continue;
arr.sort(SortNodeHot);
for (var n = 0; n < arr.length; n++) {
arr[n] = GetCopyNode(arr[n], BlockCounts);
}
}
function SortNodeHot(a, b) {
if (b.Hot !== a.Hot)
return b.Hot - a.Hot;
if (b.BlockProcessCount !== a.BlockProcessCount)
return b.BlockProcessCount - a.BlockProcessCount;
if (a.DeltaTime !== b.DeltaTime)
return a.DeltaTime - b.DeltaTime;
return a.id - b.id;
};
return { result: 1, ArrTree: ArrTree };
};
function GetCopyNode(Node, BlockCounts) {
if (!Node)
return;
if (Node.Socket && Node.Socket.Info) {
Node.Info += Node.Socket.Info + "\n";
Node.Socket.Info = "";
}
if (!Node.PrevInfo)
Node.PrevInfo = "";
var GetTiming = 0;
if (BlockCounts !== 0)
GetTiming = Math.trunc(Node.GetTiming / BlockCounts) / 1000;
var Item = {
VersionNum: Node.VersionNum,
NoSendTx: Node.NoSendTx,
GetNoSendTx: Node.GetNoSendTx,
DirectMAccount: Node.DirectMAccount,
id: Node.id,
ip: Node.ip,
portweb: Node.portweb,
port: Node.port,
TransferCount: Node.TransferCount,
GetTiming: GetTiming,
ErrCountAll: Node.ErrCountAll,
LevelCount: Node.LevelCount,
LevelEnum: Node.LevelEnum,
TimeTransfer: global.GetStrOnlyTimeUTC(new Date(Node.LastTimeTransfer)),
BlockProcessCount: Node.BlockProcessCount,
DeltaTime: Node.DeltaTime,
DeltaTimeM: Node.DeltaTimeM,
DeltaGlobTime: Node.DeltaGlobTime,
PingNumber: Node.PingNumber,
NextConnectDelta: Node.NextConnectDelta,
NextGetNodesDelta: Node.NextGetNodesDelta,
NextHotDelta: Node.NextHotDelta,
Name: Node.Name,
addrStr: Node.addrStr,
CanHot: Node.CanHot,
Active: Node.Active,
Hot: Node.Hot,
Info: Node.PrevInfo + Node.Info,
InConnectArr: Node.WasAddToConnect,
Level: Node.Level,
TransferBlockNum: Node.TransferBlockNum,
TransferSize: Node.TransferSize,
TransferBlockNumFix: Node.TransferBlockNumFix,
CurBlockNum: Node.CurBlockNum,
};
return Item;
};
global.HTTPCaller.GetBlockchainStat = function(Param) {
var Result = global.SERVER.GetStatBlockchainPeriod(Param);
Result.result = 1;
Result.sessionid = sessionid;
return Result;
};
global.HTTPCaller.GetAllCounters = function(Params, response) {
let Result = global.GET_STATS();
Result.result = 1;
Result.sessionid = sessionid;
Result.STAT_MODE = global.STAT_MODE;
if (!global.TX_PROCESS || !global.TX_PROCESS.RunRPC)
return Result;
global.TX_PROCESS.RunRPC("GET_STATS", "", function(Err, Params) {
Result.result = !Err;
if (Result.result) {
AddStatData(Params, Result, "TX");
}
if (global.WEB_PROCESS && global.WEB_PROCESS.RunRPC) {
global.WEB_PROCESS.RunRPC("GET_STATS", "", function(Err, Params) {
Result.result = !Err;
if (Result.result) {
AddStatData(Params, Result, "WEB");
}
response.end(JSON.stringify(Result));
});
}
else {
response.end(JSON.stringify(Result));
}
});
return null;
};
function AddStatData(Params, Result, Prefix) {
for (var name in Params.stats) {
for (var key in Params.stats[name]) {
var Item = Params.stats[name][key];
Result.stats[name][key + "-" + Prefix] = Item;
}
}
};
global.HTTPCaller.SetStatMode = function(flag) {
if (flag)
global.StartCommonStat();
global.STAT_MODE = flag;
global.SAVE_CONST(true);
global.TX_PROCESS.RunRPC("LOAD_CONST");
return { result: 1, sessionid: sessionid, STAT_MODE: global.STAT_MODE };
};
global.HTTPCaller.ClearStat = function() {
global.ClearCommonStat();
if (global.TX_PROCESS && global.TX_PROCESS.RunRPC) {
global.TX_PROCESS.RunRPC("ClearCommonStat", "", function(Err, Params) {
});
}
if (global.WEB_PROCESS && global.WEB_PROCESS.RunRPC) {
global.WEB_PROCESS.RunRPC("ClearCommonStat", "", function(Err, Params) {
});
}
return { result: 1, sessionid: sessionid, STAT_MODE: global.STAT_MODE };
};
global.HTTPCaller.RewriteAllTransactions = function(Param) {
global.RewriteAllTransactions();
return { result: 1, sessionid: sessionid };
};
global.HTTPCaller.RewriteTransactions = function(Param) {
var Ret = global.SERVER.ReWriteDAppTransactions(Param.BlockCount);
return { result: Ret, sessionid: sessionid };
};
global.HTTPCaller.TruncateBlockChain = function(Param) {
var StartNum = global.SERVER.BlockNumDB - Param.BlockCount;
var MinBlock = global.DApps.Accounts.GetMinBlockAct();
if (MinBlock > StartNum) {
global.ToLog("Cant Truncate BlockChain. Very long length. Max length=" + (global.SERVER.BlockNumDB - MinBlock), 0);
return { result: 0, sessionid: sessionid };
}
global.SERVER.TruncateBlockDB(StartNum);
return { result: 1, sessionid: sessionid };
};
global.HTTPCaller.ClearDataBase = function(Param) {
BlockTree.Clear();
global.SERVER.ClearDataBase();
return { result: 1, sessionid: sessionid };
};
global.HTTPCaller.CleanChain = function(Param) {
if (global.CleanChain) {
var StartNum = global.SERVER.BlockNumDB - Param.BlockCount;
global.CleanChain(StartNum);
return { result: 1, sessionid: sessionid };
}
return { result: 0, sessionid: sessionid };
};
global.HTTPCaller.GetArrStats = function(Keys, response) {
var arr = global.GET_STATDIAGRAMS(Keys);
let Result: any = { result: 1, sessionid: sessionid, arr: arr, STAT_MODE: global.STAT_MODE };
if (!global.TX_PROCESS || !global.TX_PROCESS.RunRPC)
return Result;
var Keys2 = [];
for (var i = 0; i < Keys.length; i++) {
var Str = Keys[i];
if (Str.substr(Str.length - 3) == "-TX")
Keys2.push(Str.substr(0, Str.length - 3));
}
global.TX_PROCESS.RunRPC("GET_STATDIAGRAMS", Keys2, function(Err, Arr) {
Result.result = !Err;
if (Result.result) {
for (var i = 0; i < Arr.length; i++) {
var Item = Arr[i];
Item.name = Item.name + "-TX";
Result.arr.push(Item);
}
}
var Str = JSON.stringify(Result);
response.end(Str);
});
return null;
};
global.HTTPCaller.GetBlockChain = function(type) {
if (!global.SERVER || !global.SERVER.LoadedChainList) {
return { result: 0 };
}
var MainChains = {};
for (var i = 0; i < global.SERVER.LoadedChainList.length; i++) {
var chain = global.SERVER.LoadedChainList[i];
if (chain && !chain.Deleted)
MainChains[chain.id] = true;
}
var arrBlocks = [];
var arrLoadedChainList = [];
var arrLoadedBlocks = [];
for (var key in global.SERVER.BlockChain) {
var Block = global.SERVER.BlockChain[key];
if (Block) {
arrBlocks.push(CopyBlockDraw(Block, MainChains));
}
}
AddChainList(arrLoadedChainList, global.SERVER.LoadedChainList, true);
AddMapList(arrLoadedBlocks, type, global.SERVER.MapMapLoaded, MainChains);
var ArrLoadedChainList = global.HistoryBlockBuf.LoadValue("LoadedChainList", 1);
if (ArrLoadedChainList)
for (var List of ArrLoadedChainList) {
AddChainList(arrLoadedChainList, List);
}
var ArrMapMapLoaded = global.HistoryBlockBuf.LoadValue("MapMapLoaded", 1);
if (ArrMapMapLoaded)
for (var List of ArrMapMapLoaded) {
AddMapList(arrLoadedBlocks, type, List);
}
var obj: any = {
LastCurrentBlockNum: global.SERVER.GetLastCorrectBlockNum(), CurrentBlockNum: global.SERVER.CurrentBlockNum, LoadedChainList: arrLoadedChainList,
LoadedBlocks: arrLoadedBlocks, BlockChain: arrBlocks, port: global.SERVER.port, DELTA_CURRENT_TIME: global.DELTA_CURRENT_TIME, memoryUsage: process.memoryUsage(),
IsDevelopAccount: global.IsDeveloperAccount(global.WALLET.PubKeyArr), LoadedChainCount: global.SERVER.LoadedChainList.length, StartLoadBlockTime: global.SERVER.StartLoadBlockTime,
sessionid: sessionid, result: 1
};
var obj2: any = global.HTTPCaller.GetHotArray();
obj.ArrTree = obj2.ArrTree;
arrBlocks = [];
arrLoadedChainList = [];
arrLoadedBlocks = [];
return obj;
};
global.HTTPCaller.GetHistoryTransactions = function(Params) {
if (typeof Params === "object" && Params.AccountID) {
var Account = global.DApps.Accounts.ReadState(Params.AccountID);
if (!Account)
return { result: 0 };
if (!Params.Count)
Params.Count = 100;
var arr = global.DApps.Accounts.GetHistory(Params.AccountID, Params.Count, Params.NextPos);
if (Params.GetDescription) {
for (var i = 0; i < arr.length; i++) {
var Item = arr[i];
var Block = global.SERVER.ReadBlockDB(Item.BlockNum);
if (!Block || (!Block.arrContent))
continue;
var Body = Block.arrContent[Item.TrNum];
if (!Body)
continue;
var TR = global.DApps.Accounts.GetObjectTransaction(Body);
if (TR)
Item.Description = TR.Description;
}
}
var Result: any = {
Value: {
SumCOIN: Account.Value.SumCOIN,
SumCENT: Account.Value.SumCENT
},
Name: Account.Name,
Currency: Account.Currency,
MaxBlockNum: global.GetCurrentBlockNumByTime(),
FIRST_TIME_BLOCK: global.FIRST_TIME_BLOCK,
result: arr.length > 0 ? 1 : 0,
History: arr
};
return Result;
}
return { result: 0 };
};
function GetCopyBlock(Block) {
var Result: any = {
BlockNum: Block.BlockNum,
bSave: Block.bSave,
TreeHash: global.GetHexFromAddres(Block.TreeHash),
AddrHash: global.GetHexFromAddres(Block.AddrHash),
PrevHash: global.GetHexFromAddres(Block.PrevHash),
SumHash: global.GetHexFromAddres(Block.SumHash),
SumPow: Block.SumPow, TrDataPos: Block.TrDataPos,
TrDataLen: Block.TrDataLen,
SeqHash: global.GetHexFromAddres(Block.SeqHash),
Hash: global.GetHexFromAddres(Block.Hash),
Power: global.GetPowPower(Block.PowHash),
TrCount: Block.TrCount,
arrContent: Block.arrContent,
};
return Result;
};
var AddrLength = 16;
function GetHexFromAddresShort(Hash) {
return global.GetHexFromAddres(Hash).substr(0, AddrLength);
};
function GetHexFromStrShort(Str) {
if (Str === undefined)
return Str;
else
return Str.substr(0, AddrLength);
};
var glid = 0;
function GetGUID(Block) {
if (!Block)
return "------";
if (!Block.guid) {
glid++;
Block.guid = glid;
}
return Block.guid;
};
function CopyBlockDraw(Block, MainChains) {
var MinerID = 0;
var MinerName = "";
if (Block.AddrHash) {
var Num = global.ReadUintFromArr(Block.AddrHash, 0);
MinerID = Num;
var Item = global.DApps.Accounts.ReadState(Num);
if (Item && Item.Name)
MinerName = Item.Name.substr(0, 8);
}
var CheckPoint = 0;
if (Block.BlockNum === global.CHECK_POINT.BlockNum)
CheckPoint = 1;
var Mining;
if (global.SERVER.MiningBlock === Block)
Mining = 1;
else
Mining = 0;
GetGUID(Block);
Item = {
guid: Block.guid,
Active: Block.Active,
bSave: Block.bSave,
Prepared: Block.Prepared,
BlockNum: Block.BlockNum,
Hash: GetHexFromAddresShort(Block.Hash),
SumHash: GetHexFromAddresShort(Block.SumHash),
SeqHash: GetHexFromAddresShort(Block.SeqHash),
TreeHash: GetHexFromAddresShort(Block.TreeHash),
AddrHash: GetHexFromAddresShort(Block.AddrHash),
MinerID: MinerID,
MinerName: MinerName,
Comment1: Block.Comment1,
Comment2: Block.Comment2,
SumPow: Block.SumPow,
Info: Block.Info,
TreeLoaded: Block.TreeEq,
AddToLoad: Block.AddToLoad,
LoadDB: Block.LoadDB,
FindBlockDB: Block.FindBlockDB,
TrCount: Block.TrCount,
ArrLength: 0,
TrDataLen: Block.TrDataLen,
Power: global.GetPowPower(Block.PowHash),
CheckPoint: CheckPoint,
Mining: Mining,
TransferSize: Block.TransferSize,
HasErr: Block.HasErr,
};
if (Block.chain)
Item.chainid = Block.chain.id;
if (Block.LoadDB !== undefined)
Item.bSave = Block.LoadDB;
if (Block.arrContent)
Item.TrCount = Block.arrContent.length;
Item.BlockDown = GetGUID(Block.BlockDown);
if (MainChains && Item.chainid) {
Item.Main = MainChains[Item.chainid];
}
return Item;
};
function CopyChainDraw(Chain, bWasRecursive, bMain?) {
if (!Chain)
return Chain;
GetGUID(Chain);
var Item: any = {
guid: Chain.guid, id: Chain.id, chainid: Chain.id, bSave: Chain.LoadDB, FindBlockDB: Chain.FindBlockDB, GetFindDB: Chain.GetFindDB(),
BlockNum: Chain.BlockNumStart, Hash: GetHexFromAddresShort(Chain.HashStart), Comment1: Chain.Comment1, Comment2: Chain.Comment2,
StopSend: Chain.StopSend, SumPow: 0, Info: Chain.Info, IsSum: Chain.IsSum, Main: bMain,
};
if (Chain.IsSumStart) {
Item.SumHash = Item.Hash;
Item.Hash = "-------";
}
if (Chain.RootChain) {
var rootChain = Chain.GetRootChain();
if (rootChain) {
Item.rootid = rootChain.id;
if (!bWasRecursive)
Item.root = CopyChainDraw(rootChain, true);
}
}
else
Item.rootid = "";
if (Chain.BlockHead) {
Item.HashMaxStr = GetGUID(Chain.BlockHead);
Item.BlockNumMax = Chain.BlockHead.BlockNum;
}
else {
Item.HashMaxStr = "------";
}
return Item;
};
function AddChainList(arrLoadedChainList, LoadedChainList, bMain?) {
for (var chain of LoadedChainList) {
if (chain) {
arrLoadedChainList.push(CopyChainDraw(chain, false, bMain));
}
}
};
function AddMapList(arrLoadedBlocks, type, MapMapLoaded, MainChains?) {
for (var key in MapMapLoaded) {
var map = MapMapLoaded[key];
if (map) {
for (var key in map) {
var Block = map[key];
if (key.substr(1, 1) === ":")
continue;
if (!Block.Send || type === "reload") {
arrLoadedBlocks.push(CopyBlockDraw(Block, MainChains));
Block.Send = true;
}
}
}
}
};
var MapFileHTML5 = {};
function SendWebFile(response, name?, StrCookie?, bParsing?) {
var type = name.substr(name.length - 4, 4);
if (type.substr(0, 1) === ".")
type = type.substr(1);
var Path = "./" + name;
if (!fs.existsSync(Path)) {
if (type === "ico") {
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end();
return;
}
var data = "Not found: " + name;
response.end(data);
return;
}
var StrContentType = ContenTypeMap[type];
if (!StrContentType || StrContentType === "text/html") {
var Headers = { 'Content-Type': 'text/html', "X-Frame-Options": "sameorigin" };
if (StrCookie)
Headers['Set-Cookie'] = StrCookie;
response.writeHead(200, Headers);
} else {
if (StrContentType === "application/font-woff") {
response.writeHead(200, { 'Content-Type': StrContentType, 'Access-Control-Allow-Origin': "*" });
}
else
response.writeHead(200, { 'Content-Type': StrContentType });
}
if (bParsing && StrContentType === "text/html") {
data = GetFileHTMLWithParsing(Path);
response.end(data);
return;
}
const stream = fs.createReadStream(Path);
setTimeout(function() {
stream.close();
stream.push(null);
stream.read(0);
}, 100000);
stream.pipe(response);
};
function GetFileHTMLWithParsing(Path) {
var data = global.SendHTMLMap[Path];
if (!data) {
global.SendHTMLMap[Path] = "-recursion-";
data = String(fs.readFileSync(Path));
data = ParseTag(data, "File", 0);
data = ParseTag(data, "Edit", 1);
global.SendHTMLMap[Path] = data;
}
return data;
};
var glEditNum = 0;
function ParseTag(Str, TagName, bEdit) {
var bWasInject = 0;
var data = "";
var index = 0;
while (index >= 0) {
index = Str.indexOf("{{" + TagName + "=", index);
if (index >= 0) {
var index2 = Str.indexOf("}}", index + 3 + TagName.length);
if (index2 < 0) {
//@ts-ignore
global.ToLog("Error teg " + TagName + " in " + Path);
break;
}
var Delta = index2 - index;
if (Delta > 210) {
//@ts-ignore
global.ToLog("Error length (more 200) teg File in " + Path);
break;
}
var Path2 = Str.substring(index + 3 + TagName.length, index + Delta);
data += Str.substring(0, index);
if (bEdit) {
if (!bWasInject) {
data = data + GetFileSimple("./SITE/JS/web-edit.html");
bWasInject = 1;
}
glEditNum++;
data += "<DIV class='' id='idEdit" + glEditNum + "'>";
data += GetFileHTMLFromMarkdown(Path2);
data += "</DIV>";
data += "<script>AddNewEditTag('idEdit" + glEditNum + "','" + Path2 + "');</script>";
}
else {
data += GetFileHTMLWithParsing(Path2);
}
Str = Str.substring(index2 + 2);
index = 0;
}
}
data += Str;
return data;
};
var MarkLib;
function GetFileHTMLFromMarkdown(Path) {
var data = global.SendHTMLMap[Path];
if (!data) {
if (MarkLib === undefined)
MarkLib = require("../HTML/JS/marked.js");
var Str = "";
if (fs.existsSync(Path))
Str = String(fs.readFileSync(Path));
data = MarkLib(Str);
global.SendHTMLMap[Path] = data;
}
return data;
};
function GetFileSimple(Path) {
var Key = "GetFileSimple-" + Path;
var data = global.SendHTMLMap[Key];
if (!data) {
data = String(fs.readFileSync(Path));
global.SendHTMLMap[Key] = data;
}
return data;
};
function SaveFileSimple(Path, Str) {
global.SendHTMLMap = {};
var Key = "GetFileSimple-" + Path;
global.SendHTMLMap[Key] = Str;
global.SaveToFile(Path, Str);
};
global.SendHTMLMap = {};
global.SendWebFile = SendWebFile;
global.GetFileHTMLWithParsing = GetFileHTMLWithParsing;
global.GetFileHTMLFromMarkdown = GetFileHTMLFromMarkdown;
global.GetFileSimple = GetFileSimple;
global.SaveFileSimple = SaveFileSimple;
function GetStrTime(now) {
if (!now)
now = global.GetCurrentTime(0);
var Str = "" + now.getHours().toStringZ(2);
Str = Str + ":" + now.getMinutes().toStringZ(2);
Str = Str + ":" + now.getSeconds().toStringZ(2);
return Str;
};
function OnGetData(arg) {
var response = {
end: function() {
}, writeHead: function() {
},
};
var Path = arg.path;
var obj = arg.obj;
if (Path.substr(0, 1) === "/")
Path = Path.substr(1);
var params = Path.split('/', 5);
var Ret;
var F = global.HTTPCaller[params[0]];
if (F) {
if (obj)
Ret = F(obj);
else
Ret = F(params[1], params[2], params[3]);
}
else {
Ret = { result: 0 };
}
return Ret;
};
function parseCookies(rc) {
var list = {};
rc && rc.split(';').forEach(function(cookie) {
var parts = cookie.split('=');
list[parts.shift().trim()] = decodeURI(parts.join('='));
});
return list;
};
global.SetSafeResponce = SetSafeResponce;
function SetSafeResponce(response) {
if (!response.Safe) {
response.Safe = 1;
response._end = response.end;
response._writeHead = response.writeHead;
response.end = function() {
try {
if (arguments && arguments[0] && arguments[0].length) {
global.ADD_TO_STAT("HTTP_SEND", arguments[0].length);
}
response._end.apply(response, arguments);
}
catch (e) {
global.ToError("H##1");
global.ToError(e);
}
};
response.writeHead = function() {
try {
response._writeHead.apply(response, arguments);
}
catch (e) {
global.ToError("H##2");
global.ToError(e);
}
};
}
};
if (global.HTTP_PORT_NUMBER) {
var ClientTokenMap = {};
var ClientIPMap = {};
setInterval(function() {
ClientTokenMap = {};
}, 24 * 3600 * 1000);
var port = global.HTTP_PORT_NUMBER;
var HTTPServer = http.createServer(function(request, response) {
if (!request.headers)
return;
if (!request.socket || !request.socket.remoteAddress)
return;
var remoteAddress = request.socket.remoteAddress.replace(/^.*:/, '');
if (remoteAddress === "1")
remoteAddress = "127.0.0.1";
var CheckPassword;
if (!global.HTTP_PORT_PASSWORD && remoteAddress.indexOf("127.0.0.1") < 0)
return;
if (global.HTTP_IP_CONNECT && remoteAddress.indexOf("127.0.0.1") < 0 && global.HTTP_IP_CONNECT.indexOf(remoteAddress) < 0)
return;
CheckPassword = 1;
SetSafeResponce(response);
if (!global.SERVER) {
response.writeHead(404, { 'Content-Type': 'text/html' });
response.end("");
return;
}
var fromURL = url.parse(request.url);
var Path = querystring.unescape(fromURL.path);
if (!ClientIPMap[remoteAddress]) {
ClientIPMap[remoteAddress] = 1;
global.ToLog("CONNECT TO HTTP ACCESS FROM: " + remoteAddress, 0);
global.ToLog("Path: " + Path, 0);
}
if (CheckPassword && global.HTTP_PORT_PASSWORD) {
var StrPort: any = "";
if (global.HTTP_PORT_NUMBER !== 80)
StrPort = global.HTTP_PORT_NUMBER;
var cookies = parseCookies(request.headers.cookie);
var cookies_token = cookies["token" + StrPort];
var cookies_hash = cookies["hash" + StrPort];
if (cookies_token && cookies_hash && ClientTokenMap[cookies_token] === 0) {
if (cookies_hash.substr(0, 4) !== "0000") {
SendWebFile(response, "./HTML/password.html", "token" + StrPort + "=" + cookies_token + ";path=/");
return;
}
var nonce = 0;
var index = cookies_hash.indexOf("-");
if (index > 0) {
nonce = parseInt(cookies_hash.substr(index + 1));
if (!nonce)
nonce = 0;
}
var hash = global.ClientHex(cookies_token + "-" + global.HTTP_PORT_PASSWORD, nonce);
if (hash === cookies_hash) {
ClientTokenMap[cookies_token] = 1;
}
else {
SendWebFile(response, "./HTML/password.html", "token" + StrPort + "=" + cookies_token + ";path=/");
return;
}
}
if (!cookies_token || !ClientTokenMap[cookies_token]) {
var StrToken = global.GetHexFromArr(crypto.randomBytes(16));
ClientTokenMap[StrToken] = 0;
SendWebFile(response, "./HTML/password.html", "token" + StrPort + "=" + StrToken + ";path=/");
return;
}
}
var params = Path.split('/', 6);
params.splice(0, 1);
var Type = request.method;
if (Type === "POST") {
let Response = response;
let Params = params;
let postData = "";
request.addListener("data", function(postDataChunk) {
if (postData.length < 70000 && postDataChunk.length < 70000)
postData += postDataChunk;
});
request.addListener("end", function() {
var Data;
try {
Data = JSON.parse(postData);
}
catch (e) {
global.ToError("--------Error data parsing : " + Params[0] + " " + postData.substr(0, 200));
Response.writeHead(405, { 'Content-Type': 'text/html' });
Response.end("Error data parsing");
}
if (Params[0] === "HTML")
DoCommand(response, Type, Path, [Params[1], Data], remoteAddress);
else
DoCommand(response, Type, Path, [Params[0], Data], remoteAddress);
});
}
else {
DoCommand(response, Type, Path, params, remoteAddress);
}
}).listen(port, global.LISTEN_IP, function() {
global.HTTP_SERVER_START_OK = 1;
global.ToLog("Run HTTP-server on " + global.LISTEN_IP + ":" + port);
});
HTTPServer.on('error', function(err) {
global.ToError("H##3");
global.ToError(err);
});
}
if (global.ELECTRON) {
const ipcMain = require('electron').ipcMain;
ipcMain.on('GetData', function(event, arg) {
event.returnValue = OnGetData(arg);
});
}
exports.SendData = OnGetData;
//@ts-ignore
function RunConsole(StrRun) {
var Str = fs.readFileSync("./EXPERIMENTAL/_run-console.js", { encoding: "utf8" });
if (StrRun)
Str += "\n" + StrRun;
try {
var ret = eval(Str);
}
catch (e) {
ret = e.message + "\n" + e.stack;
}
return ret;
};
var WebWalletUser = {};
function GetUserContext(Params) {
if (typeof Params.Key !== "string")
Params.Key = "" + Params.Key;
var StrKey = Params.Key + "-" + Params.Session;
var Context = WebWalletUser[StrKey];
if (!Context) {
Context = { NumDappInfo: 0, PrevDappInfo: "", NumAccountList: 0, PrevAccountList: "", LastTime: 0, FromEventNum: 0 };
WebWalletUser[StrKey] = Context;
}
return Context;
};
global.GetUserContext = GetUserContext;
global.EventNum = 0;
global.EventMap = {};
function AddDappEventToGlobalMap(Data) {
global.EventNum++;
Data.EventNum = global.EventNum;
Data.EventDate = Date.now();
var Arr = global.EventMap[Data.Smart];
if (!Arr) {
Arr = [];
global.EventMap[Data.Smart] = Arr;
}
if (Arr.length < 1000) {
Arr.push(Data);
}
};
global.AddDappEventToGlobalMap = AddDappEventToGlobalMap;
function DeleteOldEvents(SmartNum) {
var CurDate = Date.now();
var Arr = global.EventMap[SmartNum];
while (Arr && Arr.length) {
var Event = Arr[0];
if (!Event || CurDate - Event.EventDate < 5000) {
break;
}
Arr.splice(0, 1);
}
};
function GetEventArray(SmartNum, Context) {
var Arr = global.EventMap[SmartNum];
if (!Arr || Arr.length === 0) {
return [];
}
var FromEventNum = Context.FromEventNum;
var ArrRet = [];
for (var i = 0; i < Arr.length; i++) {
var Event = Arr[i];
if (Event.EventNum >= FromEventNum)
ArrRet.push(Event);
}
if (ArrRet.length) {
Context.FromEventNum = ArrRet[ArrRet.length - 1].EventNum + 1;
}
return ArrRet;
};
global.HTTPCaller.GetHashRate = function(ArrParams) {
var CurBlockNum = global.GetCurrentBlockNumByTime();
var ResArr = [];
for (var i = 0; i < ArrParams.length; i++) {
var Item = ArrParams[i];
if (!Item) {
ResArr[i] = undefined;
continue;
}
if (Item.BlockNum1 < 0)
Item.BlockNum1 = 0;
if (Item.BlockNum2 > CurBlockNum)
Item.BlockNum2 = CurBlockNum;
var Delta = Item.BlockNum2 - Item.BlockNum1;
var Count = Delta;
if (Count > 20)
Count = 20;
else
if (Count <= 0)
Count = 1;
var StepDelta = Math.floor(Delta / Count);
if (StepDelta < 1)
StepDelta = 1;
var CountAvg = 10;
if (i === ArrParams.length - 1)
CountAvg = 3;
var StepDeltaAvg = Math.floor(StepDelta / CountAvg);
if (StepDeltaAvg < 1)
StepDeltaAvg = 1;
var ItervalArr = [];
for (var Num = Item.BlockNum1; Num < Item.BlockNum2; Num += StepDelta) {
var Power;
var Item2 = BlockTree.LoadValue(Num, 1);
if (Item2 && i !== ArrParams.length - 1) {
Power = Item2.Power;
}
else {
var Sum = 0;
var CountSum = 0;
for (var d = 0; d < CountAvg; d++) {
var Block = global.SERVER.ReadBlockHeaderDB(Num + d);
if (Block) {
CountSum++;
Sum += global.GetPowPower(Block.PowHash);
}
}
if (!CountSum)
CountSum = 1;
Power = Math.floor(Sum / CountSum);
if (Power)
BlockTree.SaveValue(Num, { BlockNum: Num, Power: Power });
}
ItervalArr.push(Power);
}
ResArr[i] = ItervalArr;
}
return { result: 1, ItervalArr: ResArr };
};