204
src/core/code.ts
Normal file
204
src/core/code.ts
Normal file
@@ -0,0 +1,204 @@
|
||||
/*
|
||||
* @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 * as fs from 'fs'
|
||||
const FORMAT_EVAL_SEND = "{MaxBlockNum:uint,Code:str,Sign:arr64}";
|
||||
module.exports = class CCode extends require("./base")
|
||||
{
|
||||
LastEvalCodeNum
|
||||
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
|
||||
global.CheckCreateDir(global.GetDataPath("Update"))
|
||||
}
|
||||
CheckLoadCodeTime() {
|
||||
if (global.START_LOAD_CODE.StartLoadNode && global.START_LOAD_CODE.StartLoadVersionNum) {
|
||||
var Delta = (new Date() as any) - global.START_LOAD_CODE.StartLoadVersionNumTime;
|
||||
if (Delta > 20 * 1000) {
|
||||
global.ToError("Cannot load code version:" + global.START_LOAD_CODE.StartLoadVersionNum + " from node: " + global.START_LOAD_CODE.StartLoadNode.ip + ":" + global.START_LOAD_CODE.StartLoadNode.port)
|
||||
this.ClearLoadCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearLoadCode() {
|
||||
global.START_LOAD_CODE.StartLoad = undefined
|
||||
global.START_LOAD_CODE.StartLoadVersionNum = 0
|
||||
global.START_LOAD_CODE.StartLoadVersionNumTime = 0
|
||||
}
|
||||
StartLoadCode(Node, CodeVersion) {
|
||||
var VersionNum = CodeVersion.VersionNum;
|
||||
global.START_LOAD_CODE.StartLoad = CodeVersion
|
||||
global.START_LOAD_CODE.StartLoadNode = Node
|
||||
global.START_LOAD_CODE.StartLoadVersionNum = VersionNum
|
||||
global.START_LOAD_CODE.StartLoadVersionNumTime = new Date()
|
||||
var fname = global.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 || !global.START_LOAD_CODE.StartLoad)
|
||||
return;
|
||||
var fname = global.GetDataPath("Update/wallet-" + VersionNum + ".zip");
|
||||
if (!fs.existsSync(fname)) {
|
||||
var Hash = global.shaarr(Info.Data);
|
||||
if (global.CompareArr(Hash, global.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 {
|
||||
global.ToError("Error check hash of version code :" + global.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.global.START_LOAD_CODE.StartLoad) {
|
||||
global.CODE_VERSION = global.START_LOAD_CODE.StartLoad
|
||||
this.ClearLoadCode()
|
||||
}
|
||||
}
|
||||
SetNewCodeVersion(Data, PrivateKey) {
|
||||
var fname = global.GetDataPath("ToUpdate/wallet.zip");
|
||||
if (fs.existsSync(fname)) {
|
||||
var fname2 = global.GetDataPath("Update/wallet-" + Data.VersionNum + ".zip");
|
||||
if (fs.existsSync(fname2)) {
|
||||
fs.unlinkSync(fname2)
|
||||
}
|
||||
var data = fs.readFileSync(fname);
|
||||
var Hash = global.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(SHA3BUF(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 = global.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;
|
||||
global.ToLog("Check file:" + Name);
|
||||
if (fs.existsSync(Path)) {
|
||||
if (StartNum === Num) {
|
||||
global.ToLog("UnpackCodeFile:" + Name);
|
||||
UnpackCodeFile(Path);
|
||||
if (StartNum % 2 === 0) {
|
||||
global.RestartNode(1);
|
||||
}
|
||||
else {
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
global.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();
|
||||
global.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();
|
||||
global.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();
|
||||
global.ToLog("****************************************** RESTART!!!");
|
||||
global.ToLog("EXIT 1");
|
||||
};
|
||||
|
||||
function DoExit() {
|
||||
global.ToLog("EXIT 2");
|
||||
if (global.nw || global.NWMODE) {
|
||||
global.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 });
|
||||
}
|
||||
global.ToLog("EXIT 3");
|
||||
process.exit(0);
|
||||
};
|
||||
Reference in New Issue
Block a user