/* * @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 += "
"; data += GetFileHTMLFromMarkdown(Path2); data += "
"; data += ""; } 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 }; };