883 lines
26 KiB
JavaScript
883 lines
26 KiB
JavaScript
/*
|
|
* @project: TERA
|
|
* @version: Development (beta)
|
|
* @license: MIT (not for evil)
|
|
* @copyright: Yuriy Ivanov 2017-2019 [progr76@gmail.com]
|
|
* Web: https://terafoundation.org
|
|
* Twitter: https://twitter.com/terafoundation
|
|
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
|
*/
|
|
|
|
global.PROCESS_NAME = "MAIN";
|
|
const fs = require('fs');
|
|
const os = require('os');
|
|
require("../core/constant");
|
|
const crypto = require('crypto');
|
|
global.START_SERVER = 1;
|
|
global.DATA_PATH = GetNormalPathString(global.DATA_PATH);
|
|
global.CODE_PATH = GetNormalPathString(global.CODE_PATH);
|
|
console.log("DATA DIR: " + global.DATA_PATH);
|
|
console.log("PROGRAM DIR: " + global.CODE_PATH);
|
|
require("../core/library");
|
|
ToLog(os.platform() + " (" + os.arch() + ") " + os.release());
|
|
var VerArr = process.versions.node.split('.');
|
|
ToLog("nodejs: " + process.versions.node);
|
|
if(VerArr[0] < 8)
|
|
{
|
|
ToError("Error version of NodeJS=" + VerArr[0] + " Pls, download new version from www.nodejs.org and update it. The minimum version must be 8");
|
|
process.exit();
|
|
}
|
|
var CServer = require("../core/server");
|
|
setTimeout(function ()
|
|
{
|
|
TestSignLib(400);
|
|
}, 4000);
|
|
global.glCurNumFindArr = 0;
|
|
global.ArrReconnect = [];
|
|
global.ArrConnect = [];
|
|
var FindList = [{"ip":"91.235.136.81", "port":30005}, {"ip":"149.154.70.158", "port":30000}, ];
|
|
if(global.LOCAL_RUN)
|
|
{
|
|
FindList = [{"ip":"127.0.0.1", "port":50001}, {"ip":"127.0.0.1", "port":50002}];
|
|
}
|
|
else
|
|
if(global.TEST_NETWORK)
|
|
{
|
|
FindList = [{"ip":"149.154.70.158", "port":40000}, ];
|
|
}
|
|
global.SERVER = undefined;
|
|
global.NeedRestart = 0;
|
|
process.on('uncaughtException', function (err)
|
|
{
|
|
if(global.PROCESS_NAME !== "MAIN")
|
|
{
|
|
process.send({cmd:"log", message:err});
|
|
}
|
|
ToError(err.stack);
|
|
ToLog(err.stack);
|
|
if(err.code === "ENOTFOUND" || err.code === "ECONNRESET" || err.code === "EPIPE")
|
|
{
|
|
}
|
|
else
|
|
{
|
|
TO_ERROR_LOG("APP", 666, err);
|
|
ToLog("-----------------EXIT------------------");
|
|
process.exit();
|
|
}
|
|
});
|
|
process.on('error', function (err)
|
|
{
|
|
ToError(err.stack);
|
|
ToLog(err.stack);
|
|
});
|
|
var ArrChildProcess = [];
|
|
var WebProcess = {Name:"WEB PROCESS", idInterval:0, idInterval1:0, idInterval2:0, LastAlive:Date.now(), Worker:undefined, Path:"./process/web-process.js",
|
|
OnMessage:OnMessageWeb, PeriodAlive:3000};
|
|
if(global.HTTP_HOSTING_PORT && !global.NWMODE)
|
|
{
|
|
ArrChildProcess.push(WebProcess);
|
|
WebProcess.idInterval1 = setInterval(function ()
|
|
{
|
|
if(WebProcess.Worker && WebProcess.Worker.connected)
|
|
{
|
|
try
|
|
{
|
|
WebProcess.Worker.send({cmd:"Stat", Name:"MAX:ALL_NODES", Value:global.CountAllNode});
|
|
}
|
|
catch(e)
|
|
{
|
|
WebProcess.Worker = undefined;
|
|
}
|
|
}
|
|
}, 500);
|
|
WebProcess.idInterval2 = setInterval(function ()
|
|
{
|
|
if(WebProcess.Worker && WebProcess.Worker.connected)
|
|
{
|
|
var arr = SERVER.GetDirectNodesArray(true, true).slice(1, 500);
|
|
var arr2 = [];
|
|
var CurTime = GetCurrentTime() - 0;
|
|
for(var i = 0; i < SERVER.NodesArr.length; i++)
|
|
{
|
|
var Item = SERVER.NodesArr[i];
|
|
if(Item.LastTime && (CurTime - Item.LastTime) < 3600 * 1000)
|
|
arr2.push({ip:Item.ip});
|
|
else
|
|
if(Item.LastTimeGetNode && (CurTime - Item.LastTimeGetNode) < 3600 * 1000)
|
|
arr2.push({ip:Item.ip});
|
|
}
|
|
WebProcess.Worker.send({cmd:"NodeList", Value:arr, ValueAll:arr2});
|
|
}
|
|
}, 5000);
|
|
}
|
|
|
|
function OnMessageWeb(msg)
|
|
{
|
|
switch(msg.cmd)
|
|
{
|
|
case "SetSmartEvent":
|
|
{
|
|
if(global.TX_PROCESS && global.TX_PROCESS.Worker)
|
|
{
|
|
global.TX_PROCESS.Worker.send(msg);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
function AddTransactionFromWeb(HexValue)
|
|
{
|
|
var body = GetArrFromHex(HexValue);
|
|
if(global.TX_PROCESS && global.TX_PROCESS.Worker)
|
|
{
|
|
var StrHex = GetHexFromArr(sha3(body));
|
|
global.TX_PROCESS.Worker.send({cmd:"FindTX", TX:StrHex});
|
|
}
|
|
var Res = SERVER.AddTransaction({body:body}, 1);
|
|
var text = AddTrMap[Res];
|
|
var final = false;
|
|
if(Res <= 0 && Res !== - 3)
|
|
final = true;
|
|
ToLogClient("Send: " + text, GetHexFromArr(sha3(body)), final);
|
|
return text;
|
|
};
|
|
global.AddTransactionFromWeb = AddTransactionFromWeb;
|
|
global.STATIC_PROCESS = {Name:"STATIC PROCESS", idInterval:0, idInterval1:0, idInterval2:0, LastAlive:Date.now(), Worker:undefined,
|
|
Path:"./process/static-process.js", OnMessage:OnMessageStatic, PeriodAlive:3000};
|
|
ArrChildProcess.push(STATIC_PROCESS);
|
|
|
|
function OnMessageStatic(msg)
|
|
{
|
|
switch(msg.cmd)
|
|
{
|
|
case "Send":
|
|
{
|
|
var Node = SERVER.NodesMap[msg.addrStr];
|
|
if(Node)
|
|
{
|
|
msg.Data = msg.Data.data;
|
|
SERVER.Send(Node, msg, 1);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
global.TX_PROCESS = {Name:"TX PROCESS", idInterval:0, idInterval1:0, idInterval2:0, LastAlive:Date.now(), Worker:undefined,
|
|
Path:"./process/tx-process.js", OnMessage:OnMessageTX, PeriodAlive:100 * 1000};
|
|
ArrChildProcess.push(TX_PROCESS);
|
|
|
|
function OnMessageTX(msg)
|
|
{
|
|
switch(msg.cmd)
|
|
{
|
|
case "DappEvent":
|
|
{
|
|
if(WebProcess && WebProcess.Worker)
|
|
{
|
|
WebProcess.Worker.send(msg);
|
|
}
|
|
AddDappEventToGlobalMap(msg.Data);
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
function StartAllProcess(bClose)
|
|
{
|
|
for(var i = 0; i < ArrChildProcess.length; i++)
|
|
{
|
|
var Item = ArrChildProcess[i];
|
|
StartChildProcess(Item);
|
|
}
|
|
if(bClose)
|
|
setInterval(function ()
|
|
{
|
|
if(global.DApps && DApps.Accounts)
|
|
{
|
|
DApps.Accounts.Close();
|
|
DApps.Smart.DBSmart.Close();
|
|
}
|
|
if(WALLET && WALLET.DBHistory)
|
|
WALLET.DBHistory.Close();
|
|
}, 500);
|
|
};
|
|
var GlobalRunID = 0;
|
|
var GlobalRunMap = {};
|
|
|
|
function StartChildProcess(Item)
|
|
{
|
|
let ITEM = Item;
|
|
ITEM.idInterval = setInterval(function ()
|
|
{
|
|
var Delta = Date.now() - ITEM.LastAlive;
|
|
if(ITEM.Worker && Delta > ITEM.PeriodAlive)
|
|
{
|
|
if(ITEM.Worker)
|
|
{
|
|
ToLog("KILL PROCESS " + ITEM.Name + ": " + ITEM.Worker.pid);
|
|
try
|
|
{
|
|
process.kill(ITEM.Worker.pid, 'SIGKILL');
|
|
}
|
|
catch(e)
|
|
{
|
|
}
|
|
ITEM.Worker = undefined;
|
|
}
|
|
}
|
|
try
|
|
{
|
|
ITEM.Worker.send({cmd:"Alive"});
|
|
}
|
|
catch(e)
|
|
{
|
|
ITEM.Worker = undefined;
|
|
}
|
|
if(!ITEM.Worker)
|
|
{
|
|
ITEM.LastAlive = (Date.now()) + ITEM.PeriodAlive * 3;
|
|
ToLog("STARTING " + ITEM.Name);
|
|
ITEM.Worker = Fork(ITEM.Path, ["READONLYDB"]);
|
|
ITEM.Worker.on('message', function (msg)
|
|
{
|
|
if(ITEM.LastAlive < Date.now())
|
|
ITEM.LastAlive = Date.now();
|
|
switch(msg.cmd)
|
|
{
|
|
case "call":
|
|
var Err = 0;
|
|
var Ret;
|
|
try
|
|
{
|
|
Ret = global[msg.Name](msg.Params);
|
|
}
|
|
catch(e)
|
|
{
|
|
Err = 1;
|
|
Ret = "" + e;
|
|
}
|
|
if(msg.id && ITEM.Worker)
|
|
ITEM.Worker.send({cmd:"retcall", id:msg.id, Err:Err, Params:Ret});
|
|
break;
|
|
case "retcall":
|
|
var F = GlobalRunMap[msg.id];
|
|
if(F)
|
|
{
|
|
delete GlobalRunMap[msg.id];
|
|
F(msg.Err, msg.Params);
|
|
}
|
|
break;
|
|
case "log":
|
|
ToLog(msg.message);
|
|
break;
|
|
case "ToLogClient":
|
|
if(WebProcess && WebProcess.Worker)
|
|
{
|
|
WebProcess.Worker.send(msg);
|
|
}
|
|
ToLogClient(msg.Str, msg.StrKey, msg.bFinal);
|
|
break;
|
|
case "online":
|
|
if(ITEM.Worker)
|
|
ToLog("RUNING " + ITEM.Name + " : " + msg.message + " pid: " + ITEM.Worker.pid);
|
|
break;
|
|
default:
|
|
if(ITEM.OnMessage)
|
|
{
|
|
ITEM.OnMessage(msg);
|
|
}
|
|
break;
|
|
}
|
|
});
|
|
}
|
|
}, 500);
|
|
ITEM.RunRPC = function (Name,Params,F)
|
|
{
|
|
if(!ITEM.Worker)
|
|
return ;
|
|
if(F)
|
|
{
|
|
GlobalRunID++;
|
|
try
|
|
{
|
|
ITEM.Worker.send({cmd:"call", id:GlobalRunID, Name:Name, Params:Params});
|
|
GlobalRunMap[GlobalRunID] = F;
|
|
}
|
|
catch(e)
|
|
{
|
|
}
|
|
}
|
|
else
|
|
{
|
|
ITEM.Worker.send({cmd:"call", id:0, Name:Name, Params:Params});
|
|
}
|
|
};
|
|
};
|
|
global.StopChildProcess = function ()
|
|
{
|
|
for(var i = 0; i < ArrChildProcess.length; i++)
|
|
{
|
|
var Item = ArrChildProcess[i];
|
|
if(Item.idInterval)
|
|
clearInterval(Item.idInterval);
|
|
Item.idInterval = 0;
|
|
if(Item.idInterval1)
|
|
clearInterval(Item.idInterval1);
|
|
Item.idInterval1 = 0;
|
|
if(Item.idInterval2)
|
|
clearInterval(Item.idInterval2);
|
|
Item.idInterval2 = 0;
|
|
if(Item.Worker && Item.Worker.connected)
|
|
{
|
|
Item.Worker.send({cmd:"Exit"});
|
|
Item.Worker = undefined;
|
|
}
|
|
}
|
|
RunStopPOWProcess("STOP");
|
|
};
|
|
require("../core/html-server");
|
|
RunServer();
|
|
setInterval(function run1()
|
|
{
|
|
DoConnectToNodes(ArrReconnect, "RECONNECT");
|
|
}, 200);
|
|
setInterval(function run2()
|
|
{
|
|
DoGetNodes();
|
|
DoConnectToNodes(ArrConnect, "CONNECT");
|
|
}, 500);
|
|
var StartCheckMining = 0;
|
|
global.MiningPaused = 0;
|
|
var ProcessMemorySize = 0;
|
|
global.ArrMiningWrk = [];
|
|
var BlockMining;
|
|
if(global.ADDRLIST_MODE)
|
|
{
|
|
return ;
|
|
}
|
|
|
|
function AllAlive()
|
|
{
|
|
for(var i = 0; i < ArrMiningWrk.length; i++)
|
|
{
|
|
ArrMiningWrk[i].send({cmd:"Alive"});
|
|
}
|
|
};
|
|
|
|
function ClearArrMining()
|
|
{
|
|
for(var i = 0; i < ArrMiningWrk.length; i++)
|
|
{
|
|
ArrMiningWrk[i].send({cmd:"Exit"});
|
|
}
|
|
ArrMiningWrk = [];
|
|
};
|
|
|
|
function RunStopPOWProcess(Mode)
|
|
{
|
|
if(!GetCountMiningCPU() || GetCountMiningCPU() <= 0)
|
|
return ;
|
|
if(!StartCheckMining)
|
|
{
|
|
StartCheckMining = 1;
|
|
setInterval(RunStopPOWProcess, CHECK_RUN_MINING);
|
|
setInterval(AllAlive, 1000);
|
|
}
|
|
if(global.NeedRestart)
|
|
return ;
|
|
if(global.USE_MINING && global.MINING_START_TIME && global.MINING_PERIOD_TIME)
|
|
{
|
|
var Time = GetCurrentTime();
|
|
var TimeCur = Time.getUTCHours() * 3600 + Time.getUTCMinutes() * 60 + Time.getUTCSeconds();
|
|
var StartTime = GetSecFromStrTime(global.MINING_START_TIME);
|
|
var RunPeriod = GetSecFromStrTime(global.MINING_PERIOD_TIME);
|
|
var TimeEnd = StartTime + RunPeriod;
|
|
global.MiningPaused = 1;
|
|
if(TimeCur >= StartTime && TimeCur <= TimeEnd)
|
|
{
|
|
global.MiningPaused = 0;
|
|
}
|
|
else
|
|
{
|
|
StartTime -= 24 * 3600;
|
|
TimeEnd -= 24 * 3600;
|
|
if(TimeCur >= StartTime && TimeCur <= TimeEnd)
|
|
{
|
|
global.MiningPaused = 0;
|
|
}
|
|
}
|
|
if(ArrMiningWrk.length && global.MiningPaused)
|
|
{
|
|
ToLog("------------ MINING MUST STOP ON TIME");
|
|
ClearArrMining();
|
|
return ;
|
|
}
|
|
else
|
|
if(!ArrMiningWrk.length && !global.MiningPaused)
|
|
{
|
|
ToLog("*********** MINING MUST START ON TIME");
|
|
}
|
|
else
|
|
{
|
|
return ;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
global.MiningPaused = 0;
|
|
}
|
|
if(!global.USE_MINING || Mode === "STOP")
|
|
{
|
|
ClearArrMining();
|
|
return ;
|
|
}
|
|
if(global.USE_MINING && ArrMiningWrk.length)
|
|
return ;
|
|
if(SERVER.LoadHistoryMode)
|
|
return ;
|
|
if(GENERATE_BLOCK_ACCOUNT < 8)
|
|
return ;
|
|
var PathMiner = GetCodePath("../miner.js");
|
|
if(!fs.existsSync(PathMiner))
|
|
PathMiner = "./process/pow-process.js";
|
|
if(ArrMiningWrk.length >= GetCountMiningCPU())
|
|
return ;
|
|
if(GrayConnect())
|
|
{
|
|
ToLog("CANNOT START MINER IN NOT DIRECT IP MODE");
|
|
return ;
|
|
}
|
|
var Memory;
|
|
if(global.SIZE_MINING_MEMORY)
|
|
Memory = global.SIZE_MINING_MEMORY;
|
|
else
|
|
{
|
|
Memory = os.freemem() - (512 + GetCountMiningCPU() * 100) * 1024 * 1014;
|
|
if(Memory < 0)
|
|
{
|
|
ToLog("Not enough memory to start processes.");
|
|
return ;
|
|
}
|
|
}
|
|
ProcessMemorySize = Math.trunc(Memory / GetCountMiningCPU());
|
|
ToLog("START MINER PROCESS COUNT: " + GetCountMiningCPU() + " Memory: " + ProcessMemorySize / 1024 / 1024 + " Mb for eatch process");
|
|
for(var R = 0; R < GetCountMiningCPU(); R++)
|
|
{
|
|
let Worker = Fork(PathMiner);
|
|
ArrMiningWrk.push(Worker);
|
|
Worker.Num = ArrMiningWrk.length;
|
|
Worker.on('message', function (msg)
|
|
{
|
|
if(msg.cmd === "log")
|
|
{
|
|
ToLog(msg.message);
|
|
}
|
|
else
|
|
if(msg.cmd === "online")
|
|
{
|
|
Worker.bOnline = true;
|
|
ToLog("RUNING PROCESS:" + Worker.Num + ":" + msg.message);
|
|
}
|
|
else
|
|
if(msg.cmd === "POW")
|
|
{
|
|
SERVER.MiningProcess(msg);
|
|
}
|
|
else
|
|
if(msg.cmd === "HASHRATE")
|
|
{
|
|
ADD_HASH_RATE(msg.CountNonce);
|
|
}
|
|
});
|
|
Worker.on('error', function (err)
|
|
{
|
|
if(!ArrMiningWrk.length)
|
|
return ;
|
|
ToError('ERROR IN PROCESS: ' + err);
|
|
});
|
|
Worker.on('close', function (code)
|
|
{
|
|
ToLog("STOP PROCESS: " + Worker.Num + " pid:" + Worker.pid);
|
|
for(var i = 0; i < ArrMiningWrk.length; i++)
|
|
{
|
|
if(ArrMiningWrk[i].pid === Worker.pid)
|
|
{
|
|
ToLog("Delete wrk from arr - pid:" + Worker.pid);
|
|
ArrMiningWrk.splice(i, 1);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
};
|
|
|
|
function SetCalcPOW(Block,cmd)
|
|
{
|
|
if(!global.USE_MINING)
|
|
return ;
|
|
if(ArrMiningWrk.length !== GetCountMiningCPU())
|
|
return ;
|
|
BlockMining = Block;
|
|
for(var i = 0; i < ArrMiningWrk.length; i++)
|
|
{
|
|
var CurWorker = ArrMiningWrk[i];
|
|
if(!CurWorker.bOnline)
|
|
continue;
|
|
CurWorker.send({cmd:cmd, BlockNum:Block.BlockNum, Account:GENERATE_BLOCK_ACCOUNT, MinerID:GENERATE_BLOCK_ACCOUNT, SeqHash:Block.SeqHash,
|
|
Hash:Block.Hash, PrevHash:Block.PrevHash, Time:Date.now(), Num:CurWorker.Num, RunPeriod:global.POWRunPeriod, RunCount:global.POW_RUN_COUNT,
|
|
RunCountFind:global.POW_RUN_COUNT_FIND, Percent:global.POW_MAX_PERCENT, CountMiningCPU:GetCountMiningCPU(), ProcessMemorySize:ProcessMemorySize,
|
|
});
|
|
}
|
|
};
|
|
global.SetCalcPOW = SetCalcPOW;
|
|
global.RunStopPOWProcess = RunStopPOWProcess;
|
|
|
|
function DoGetNodes()
|
|
{
|
|
if(!SERVER)
|
|
return ;
|
|
if(!GrayConnect() && SERVER.CanSend < 2)
|
|
return ;
|
|
if(!SERVER.NodesArrUnSort || !SERVER.NodesArrUnSort.length)
|
|
return ;
|
|
var Num = glCurNumFindArr % SERVER.NodesArrUnSort.length;
|
|
var Node = SERVER.NodesArrUnSort[Num];
|
|
if(Num === 0)
|
|
glCurNumFindArr = 0;
|
|
glCurNumFindArr++;
|
|
if(Node.Delete)
|
|
return ;
|
|
if(SERVER.NodeInBan(Node))
|
|
return ;
|
|
if(SERVER.BusyLevel && Node.BlockProcessCount <= SERVER.BusyLevel)
|
|
return ;
|
|
if(GetSocketStatus(Node.Socket) === 100)
|
|
{
|
|
SERVER.StartGetNodes(Node);
|
|
}
|
|
};
|
|
|
|
function DoConnectToNodes(Arr,Mode)
|
|
{
|
|
if(!SERVER)
|
|
return ;
|
|
if(!GrayConnect() && SERVER.CanSend < 2)
|
|
{
|
|
return ;
|
|
}
|
|
if(GrayConnect() && SERVER.ActualNodes.size > GetGrayServerConnections())
|
|
return ;
|
|
if(Arr.length)
|
|
{
|
|
var MinProcessCount = SERVER.BusyLevel - 1;
|
|
for(var i = 0; i < Arr.length; i++)
|
|
{
|
|
var Node = Arr[i];
|
|
if(Node.BlockProcessCount > MinProcessCount)
|
|
{
|
|
Arr.splice(i, 1);
|
|
if(Mode === "CONNECT")
|
|
{
|
|
Node.WasAddToConnect = undefined;
|
|
SERVER.StartConnectTry(Node);
|
|
}
|
|
else
|
|
if(Mode === "RECONNECT")
|
|
{
|
|
Node.WasAddToReconnect = undefined;
|
|
Node.CreateConnect();
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
var idRunOnce;
|
|
|
|
function RunServer()
|
|
{
|
|
idRunOnce = setInterval(RunOnce, 1000);
|
|
ToLog("NETWORK: " + GetNetworkName());
|
|
ToLog("VERSION: " + DEF_VERSION);
|
|
if(global.NET_WORK_MODE)
|
|
{
|
|
global.START_IP = NET_WORK_MODE.ip;
|
|
global.START_PORT_NUMBER = NET_WORK_MODE.port;
|
|
}
|
|
var KeyPair = crypto.createECDH('secp256k1');
|
|
if(!global.SERVER_PRIVATE_KEY_HEX || global.NEW_SERVER_PRIVATE_KEY)
|
|
{
|
|
while(true)
|
|
{
|
|
var Arr = crypto.randomBytes(32);
|
|
KeyPair.setPrivateKey(Buffer.from(Arr));
|
|
var Arr2 = KeyPair.getPublicKey('', 'compressed');
|
|
if(Arr2[0] === 2)
|
|
break;
|
|
}
|
|
global.SERVER_PRIVATE_KEY_HEX = GetHexFromArr(Arr);
|
|
SAVE_CONST(true);
|
|
}
|
|
var ServerPrivKey = GetArrFromHex(global.SERVER_PRIVATE_KEY_HEX);
|
|
if(global.USE_NET_FOR_SERVER_ADDRES)
|
|
{
|
|
const os = require('os');
|
|
var map = os.networkInterfaces();
|
|
main:
|
|
for(var key in map)
|
|
{
|
|
var arr = map[key];
|
|
for(var i = 0; i < arr.length; i++)
|
|
{
|
|
var item = arr[i];
|
|
if(!item.internal && item.mac !== "00:00:00:00:00:00")
|
|
{
|
|
ServerPrivKey = sha3(global.SERVER_PRIVATE_KEY_HEX + ":" + item.mac + ":" + global.START_PORT_NUMBER);
|
|
break main;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
KeyPair.setPrivateKey(Buffer.from(ServerPrivKey));
|
|
new CServer(KeyPair, START_IP, START_PORT_NUMBER, false, false);
|
|
DoStartFindList();
|
|
};
|
|
|
|
function DoStartFindList()
|
|
{
|
|
var keyThisServer = SERVER.ip + ":" + SERVER.port;
|
|
for(var n = 0; n < FindList.length; n++)
|
|
{
|
|
var item = FindList[n];
|
|
if(!item.ip)
|
|
continue;
|
|
var key = item.ip + ":" + item.port;
|
|
if(keyThisServer === key)
|
|
continue;
|
|
var addrStr = GetHexFromAddres(crypto.randomBytes(32));
|
|
var Node = SERVER.GetNewNode(addrStr, item.ip, item.port);
|
|
Node.addrStrTemp = addrStr;
|
|
Node.StartFindList = 1;
|
|
}
|
|
};
|
|
|
|
function RunOnce()
|
|
{
|
|
if(global.SERVER && global.SERVER.CheckOnStartComplete)
|
|
{
|
|
clearInterval(idRunOnce);
|
|
RunOnUpdate();
|
|
StartAllProcess(1);
|
|
require("./dogs");
|
|
if(global.RESTART_PERIOD_SEC)
|
|
{
|
|
var Period = (random(600) + global.RESTART_PERIOD_SEC);
|
|
ToLog("SET RESTART NODE AFTER: " + Period + " sec");
|
|
setInterval(function ()
|
|
{
|
|
RestartNode();
|
|
}, Period * 1000);
|
|
}
|
|
setTimeout(function ()
|
|
{
|
|
RunStopPOWProcess();
|
|
}, 10000);
|
|
}
|
|
};
|
|
|
|
function RunOnUpdate()
|
|
{
|
|
if(!UPDATE_NUM_COMPLETE)
|
|
UPDATE_NUM_COMPLETE = 0;
|
|
var CurNum = UPDATE_NUM_COMPLETE;
|
|
if(CurNum !== UPDATE_CODE_VERSION_NUM)
|
|
{
|
|
global.UPDATE_NUM_COMPLETE = UPDATE_CODE_VERSION_NUM;
|
|
ToLog("UPDATER Start");
|
|
SAVE_CONST(true);
|
|
if(global.TEST_NETWORK)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
}
|
|
ToLog("UPDATER Finish");
|
|
}
|
|
};
|
|
|
|
function CheckRewriteTr(Num,StrHash,StartRewrite)
|
|
{
|
|
if(SERVER.BlockNumDB < StartRewrite)
|
|
return "NO";
|
|
var AccountsHash = DApps.Accounts.GetHashOrUndefined(Num);
|
|
if(!AccountsHash || GetHexFromArr(AccountsHash) !== StrHash)
|
|
{
|
|
ToLog("START REWRITE ERR ACTS TRANSACTIONS");
|
|
SERVER.ReWriteDAppTransactions(SERVER.BlockNumDB - StartRewrite);
|
|
return "Rewrite";
|
|
}
|
|
else
|
|
{
|
|
return "OK";
|
|
}
|
|
};
|
|
|
|
function CheckRewriteAllTr2(Num,StrHash,Num2,StrHash2)
|
|
{
|
|
if(global.LOCAL_RUN || global.TEST_NETWORK)
|
|
return "NONE";
|
|
var MaxNum = SERVER.GetMaxNumBlockDB();
|
|
if(MaxNum < START_BLOCK_ACCOUNT_HASH)
|
|
return "NONE";
|
|
var AccountsHash = DApps.Accounts.GetHashOrUndefined(Num);
|
|
var AccountsHash2 = DApps.Accounts.GetHashOrUndefined(Num2);
|
|
if(AccountsHash2 && GetHexFromArr(AccountsHash2) === StrHash2)
|
|
return "OK";
|
|
if(AccountsHash && GetHexFromArr(AccountsHash) !== StrHash)
|
|
{
|
|
ToLog("***************** START REWRITE ALL DAPPS");
|
|
global.UpdateMode = 1;
|
|
for(var key in DApps)
|
|
{
|
|
DApps[key].ClearDataBase();
|
|
}
|
|
global.UpdateMode = 0;
|
|
return "Rewrite";
|
|
}
|
|
else
|
|
{
|
|
return "OK";
|
|
}
|
|
};
|
|
|
|
function CheckRewriteAllTr(Num,StrHash,Num2,StrHash2)
|
|
{
|
|
if(global.LOCAL_RUN || global.TEST_NETWORK)
|
|
return "NONE";
|
|
var MaxNum = SERVER.GetMaxNumBlockDB();
|
|
if(MaxNum < START_BLOCK_ACCOUNT_HASH)
|
|
return "NONE";
|
|
var AccountsHash = DApps.Accounts.GetHashOrUndefined(Num);
|
|
if(AccountsHash && GetHexFromArr(AccountsHash) !== StrHash)
|
|
{
|
|
ToLog("***************** START REWRITE ALL DAPPS");
|
|
global.UpdateMode = 1;
|
|
for(var key in DApps)
|
|
{
|
|
DApps[key].ClearDataBase();
|
|
}
|
|
global.UpdateMode = 0;
|
|
return "Rewrite";
|
|
}
|
|
else
|
|
{
|
|
return "OK";
|
|
}
|
|
};
|
|
global.CheckRewriteTr = CheckRewriteTr;
|
|
var glPortDebug = 49800;
|
|
|
|
function Fork(Path,ArrArgs)
|
|
{
|
|
const child_process = require('child_process');
|
|
ArrArgs = ArrArgs || [];
|
|
if(global.LOCAL_RUN)
|
|
ArrArgs.push("LOCALRUN");
|
|
else
|
|
if(global.TEST_NETWORK)
|
|
ArrArgs.push("TESTRUN");
|
|
ArrArgs.push("PATH:" + global.DATA_PATH);
|
|
ArrArgs.push("HOSTING:" + global.HTTP_HOSTING_PORT);
|
|
if(!global.USE_PARAM_JS)
|
|
ArrArgs.push("NOPARAMJS");
|
|
if(global.NWMODE)
|
|
ArrArgs.push("NWMODE");
|
|
if(global.NOALIVE)
|
|
ArrArgs.push("NOALIVE");
|
|
if(global.DEV_MODE)
|
|
ArrArgs.push("DEV_MODE");
|
|
glPortDebug++;
|
|
var execArgv = [];
|
|
var Worker = child_process.fork(Path, ArrArgs, {execArgv:execArgv});
|
|
return Worker;
|
|
};
|
|
|
|
function FixBlockBug12970020()
|
|
{
|
|
var Block = SERVER.ReadBlockHeaderDB(12970020);
|
|
if(!Block)
|
|
return ;
|
|
CorrectBlockBug12970020(Block);
|
|
var BufWrite = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE);
|
|
SERVER.BlockHeaderToBuf(BufWrite, Block);
|
|
var Ret = SERVER.WriteBufHeaderDB(BufWrite, Block.BlockNum);
|
|
return Ret;
|
|
};
|
|
|
|
function CorrectBlockBug12970020(Block)
|
|
{
|
|
Block.TreeHash = GetArrFromHex("9FE0A443BD42E70206133119D6D13638D422E34BD5CC38A7A12368EB4A8A1D4F");
|
|
CreateHashMinimal(Block, 0);
|
|
Block.SumPow = 367146128;
|
|
};
|
|
|
|
function RecreateAccountHashDB()
|
|
{
|
|
var name = "accounts-hash";
|
|
var fname = GetDataPath("DB/" + name);
|
|
if(fs.existsSync(fname))
|
|
{
|
|
global.UpdateMode = 1;
|
|
ToLog("Start updating " + name);
|
|
const DBRow = require("../core/db/db-row");
|
|
var DB0 = new DBRow(name, 6 + 32 + 12, "{BlockNum:uint,Hash:hash, Reserve: arr12}");
|
|
var DB2 = DApps.Accounts.DBAccountsHash;
|
|
for(var num = START_BLOCK_ACCOUNT_HASH; true; num += PERIOD_ACCOUNT_HASH)
|
|
{
|
|
var Item = DB0.Read(num);
|
|
if(!Item)
|
|
break;
|
|
var Block = SERVER.ReadBlockHeaderDB(num);
|
|
if(!Block)
|
|
break;
|
|
var Data = {Num:Block.BlockNum / PERIOD_ACCOUNT_HASH, BlockNum:Block.BlockNum, Hash:Item.Hash, SumHash:Block.SumHash};
|
|
DB2.Write(Data);
|
|
DB2.Truncate(Block.BlockNum / PERIOD_ACCOUNT_HASH);
|
|
}
|
|
ToLog("Finish updating " + name);
|
|
DB0.Close();
|
|
DB2.Close();
|
|
global.UpdateMode = 0;
|
|
fs.unlinkSync(fname);
|
|
}
|
|
};
|
|
global.TestSignLib = TestSignLib;
|
|
|
|
function TestSignLib(MaxTime)
|
|
{
|
|
var hash = Buffer.from(GetArrFromHex("A6B0914953F515F4686B2BA921B8FAC66EE6A6D3E317B43E981EBBA52393BFC6"));
|
|
var PubKey = Buffer.from(GetArrFromHex("026A04AB98D9E4774AD806E302DDDEB63BEA16B5CB5F223EE77478E861BB583EB3"));
|
|
var Sign = Buffer.from(GetArrFromHex("5D5382C65E4C1E8D412D5F30F87B8F72F371E9E4FC170761BCE583A961CF44966F92B38D402BC1CBCB7567335051A321B93F4E32112129AED4AB602E093A1187"));
|
|
var startTime = process.hrtime();
|
|
for(var Num = 0; Num < 1000; Num++)
|
|
{
|
|
var Result = secp256k1.verify(hash, Sign, PubKey);
|
|
if(!Result)
|
|
{
|
|
ToError("Error test sign");
|
|
process.exit(0);
|
|
}
|
|
var Time = process.hrtime(startTime);
|
|
var deltaTime = Time[0] * 1000 + Time[1] / 1e6;
|
|
if(deltaTime > MaxTime)
|
|
{
|
|
ToLog("*************** WARNING: VERY SLOW LIBRARY: secp256k1 ***************");
|
|
ToLog("You can only process: " + Num + " transactions");
|
|
ToLog("Install all dependent packages and run the installation command:\ncd Source/node_modules/secp256k1 \nnode-gyp build");
|
|
return 0;
|
|
}
|
|
}
|
|
ToLog("TestSignLib: " + Math.trunc(deltaTime) + " ms");
|
|
return 1;
|
|
};
|