246 lines
7.2 KiB
JavaScript
246 lines
7.2 KiB
JavaScript
/*
|
|
* @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://web.telegram.org/#/im?p=@terafoundation
|
|
*/
|
|
|
|
"use strict";
|
|
var fs = require("fs");
|
|
const FORMAT_EVAL_SEND = "{MaxBlockNum:uint,Code:str,Sign:arr64}";
|
|
module.exports = class CCode extends require("./base")
|
|
{
|
|
constructor(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
|
{
|
|
super(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
|
if(!global.ADDRLIST_MODE && !this.VirtualMode)
|
|
{
|
|
setInterval(this.CheckLoadCodeTime.bind(this), 10 * 1000)
|
|
}
|
|
this.LastEvalCodeNum = 0
|
|
CheckCreateDir(GetDataPath("Update"))
|
|
}
|
|
CheckLoadCodeTime()
|
|
{
|
|
if(START_LOAD_CODE.StartLoadNode && START_LOAD_CODE.StartLoadVersionNum)
|
|
{
|
|
var Delta = new Date() - START_LOAD_CODE.StartLoadVersionNumTime;
|
|
if(Delta > 20 * 1000)
|
|
{
|
|
ToError("Cannot load code version:" + START_LOAD_CODE.StartLoadVersionNum + " from node: " + START_LOAD_CODE.StartLoadNode.ip + ":" + START_LOAD_CODE.StartLoadNode.port)
|
|
this.ClearLoadCode()
|
|
}
|
|
}
|
|
}
|
|
ClearLoadCode()
|
|
{
|
|
START_LOAD_CODE.StartLoad = undefined
|
|
START_LOAD_CODE.StartLoadVersionNum = 0
|
|
START_LOAD_CODE.StartLoadVersionNumTime = 0
|
|
}
|
|
StartLoadCode(Node, CodeVersion)
|
|
{
|
|
var VersionNum = CodeVersion.VersionNum;
|
|
START_LOAD_CODE.StartLoad = CodeVersion
|
|
START_LOAD_CODE.StartLoadNode = Node
|
|
START_LOAD_CODE.StartLoadVersionNum = VersionNum
|
|
START_LOAD_CODE.StartLoadVersionNumTime = new Date()
|
|
var fname = GetDataPath("Update/wallet-" + VersionNum + ".zip");
|
|
if(fs.existsSync(fname))
|
|
{
|
|
this.UseCode(VersionNum, false)
|
|
return ;
|
|
}
|
|
var Context = {"VersionNum":VersionNum};
|
|
this.SendF(Node, {"Method":"GETCODE", "Context":Context, "Data":VersionNum})
|
|
}
|
|
static
|
|
GETCODE_F()
|
|
{
|
|
return "uint";
|
|
}
|
|
RETCODE(Info)
|
|
{
|
|
var VersionNum = Info.Context.VersionNum;
|
|
if(!VersionNum || !START_LOAD_CODE.StartLoad)
|
|
return ;
|
|
var fname = GetDataPath("Update/wallet-" + VersionNum + ".zip");
|
|
if(!fs.existsSync(fname))
|
|
{
|
|
var Hash = shaarr(Info.Data);
|
|
if(CompareArr(Hash, START_LOAD_CODE.StartLoad.Hash) === 0)
|
|
{
|
|
var file_handle = fs.openSync(fname, "w");
|
|
fs.writeSync(file_handle, Info.Data, 0, Info.Data.length)
|
|
fs.closeSync(file_handle)
|
|
this.UseCode(VersionNum, global.USE_AUTO_UPDATE)
|
|
}
|
|
else
|
|
{
|
|
ToError("Error check hash of version code :" + START_LOAD_CODE.StartLoadVersionNum + " from node: " + Info.Node.ip + ":" + Info.Node.port)
|
|
this.ClearLoadCode()
|
|
this.AddCheckErrCount(Info.Node, 1, "Error check hash of version code")
|
|
}
|
|
}
|
|
}
|
|
UseCode(VersionNum, bUpdate)
|
|
{
|
|
if(bUpdate)
|
|
{
|
|
UpdateCodeFiles(VersionNum)
|
|
}
|
|
if(global.START_LOAD_CODE.StartLoad)
|
|
{
|
|
global.CODE_VERSION = START_LOAD_CODE.StartLoad
|
|
this.ClearLoadCode()
|
|
}
|
|
}
|
|
SetNewCodeVersion(Data, PrivateKey)
|
|
{
|
|
var fname = GetDataPath("ToUpdate/wallet.zip");
|
|
if(fs.existsSync(fname))
|
|
{
|
|
var fname2 = GetDataPath("Update/wallet-" + Data.VersionNum + ".zip");
|
|
if(fs.existsSync(fname2))
|
|
{
|
|
fs.unlinkSync(fname2)
|
|
}
|
|
var data = fs.readFileSync(fname);
|
|
var Hash = shaarr(data);
|
|
var file_handle = fs.openSync(fname2, "w");
|
|
fs.writeSync(file_handle, data, 0, data.length)
|
|
fs.closeSync(file_handle)
|
|
var SignArr = arr2(Hash, GetArrFromValue(Data.VersionNum));
|
|
var Sign = secp256k1.sign(shabuf(SignArr), PrivateKey).signature;
|
|
global.CODE_VERSION = Data
|
|
global.CODE_VERSION.Hash = Hash
|
|
global.CODE_VERSION.Sign = Sign
|
|
return "OK Set new code version=" + Data.VersionNum;
|
|
}
|
|
else
|
|
{
|
|
return "File not exist: " + fname;
|
|
}
|
|
}
|
|
};
|
|
|
|
function UpdateCodeFiles(StartNum)
|
|
{
|
|
var fname = GetDataPath("Update");
|
|
if(!fs.existsSync(fname))
|
|
return 0;
|
|
var arr = fs.readdirSync(fname);
|
|
var arr2 = [];
|
|
for(var i = 0; i < arr.length; i++)
|
|
{
|
|
if(arr[i].substr(0, 7) === "wallet-")
|
|
{
|
|
arr2.push(parseInt(arr[i].substr(7)));
|
|
}
|
|
}
|
|
arr2.sort(function (a,b)
|
|
{
|
|
return a - b;
|
|
});
|
|
for(var i = 0; i < arr2.length; i++)
|
|
{
|
|
var Num = arr2[i];
|
|
var Name = "wallet-" + Num + ".zip";
|
|
var Path = fname + "/" + Name;
|
|
ToLog("Check file:" + Name);
|
|
if(fs.existsSync(Path))
|
|
{
|
|
if(StartNum === Num)
|
|
{
|
|
ToLog("UnpackCodeFile:" + Name);
|
|
UnpackCodeFile(Path);
|
|
if(StartNum % 2 === 0)
|
|
{
|
|
global.RestartNode(1);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
return 1;
|
|
}
|
|
else
|
|
{
|
|
ToLog("Delete old file update:" + Name);
|
|
fs.unlinkSync(Path);
|
|
}
|
|
}
|
|
}
|
|
return 0;
|
|
};
|
|
global.UnpackCodeFile = UnpackCodeFile;
|
|
|
|
function UnpackCodeFile(fname)
|
|
{
|
|
var data = fs.readFileSync(fname);
|
|
var reader = ZIP.Reader(data);
|
|
reader.forEach(function (entry)
|
|
{
|
|
var Name = entry.getName();
|
|
var Path = GetCodePath(Name);
|
|
if(entry.isFile())
|
|
{
|
|
var buf = entry.getData();
|
|
CheckCreateDir(Path, true, true);
|
|
var file_handle = fs.openSync(Path, "w");
|
|
fs.writeSync(file_handle, buf, 0, buf.length);
|
|
fs.closeSync(file_handle);
|
|
}
|
|
else
|
|
{
|
|
}
|
|
});
|
|
reader.close();
|
|
};
|
|
global.RestartNode = function RestartNode(bForce)
|
|
{
|
|
global.NeedRestart = 1;
|
|
setTimeout(DoExit, 5000);
|
|
if(global.nw || global.NWMODE)
|
|
{
|
|
}
|
|
else
|
|
{
|
|
StopChildProcess();
|
|
ToLog("********************************** FORCE RESTART!!!");
|
|
return ;
|
|
}
|
|
if(this.ActualNodes)
|
|
{
|
|
var it = this.ActualNodes.iterator(), Node;
|
|
while((Node = it.next()) !== null)
|
|
{
|
|
if(Node.Socket)
|
|
CloseSocket(Node.Socket, "Restart");
|
|
}
|
|
}
|
|
this.StopServer();
|
|
this.StopNode();
|
|
StopChildProcess();
|
|
ToLog("****************************************** RESTART!!!");
|
|
ToLog("EXIT 1");
|
|
};
|
|
|
|
function DoExit()
|
|
{
|
|
ToLog("EXIT 2");
|
|
if(global.nw || global.NWMODE)
|
|
{
|
|
ToLog("RESTART NW");
|
|
var StrRun = '"' + process.argv[0] + '" .\n';
|
|
StrRun += '"' + process.argv[0] + '" .\n';
|
|
SaveToFile("run-next.bat", StrRun);
|
|
const child_process = require('child_process');
|
|
child_process.exec("run-next.bat", {shell:true});
|
|
}
|
|
ToLog("EXIT 3");
|
|
process.exit(0);
|
|
};
|