2019-07-10 04:01:15 +00:00
|
|
|
/*
|
|
|
|
* @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'
|
2019-07-11 05:35:16 +00:00
|
|
|
import CCommon from './base'
|
2019-07-11 07:52:17 +00:00
|
|
|
import { secp256k1 } from '../core/library'
|
2019-07-10 10:07:35 +00:00
|
|
|
// const FORMAT_EVAL_SEND = "{MaxBlockNum:uint,Code:str,Sign:arr64}";
|
2019-07-11 05:35:16 +00:00
|
|
|
export default class CCode extends CCommon {
|
2019-07-10 04:01:15 +00:00
|
|
|
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)
|
|
|
|
}
|
2019-07-10 07:59:04 +00:00
|
|
|
if (global.START_LOAD_CODE.StartLoad) {
|
2019-07-10 04:01:15 +00:00
|
|
|
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)
|
2019-07-10 07:59:04 +00:00
|
|
|
var SignArr = global.arr2(Hash, global.GetArrFromValue(Data.VersionNum));
|
2019-07-11 07:52:17 +00:00
|
|
|
var Sign = secp256k1.sign(global.SHA3BUF(SignArr), PrivateKey).signature;
|
2019-07-10 04:01:15 +00:00
|
|
|
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);
|
2019-07-10 07:59:04 +00:00
|
|
|
var reader = global.ZIP.Reader(data);
|
2019-07-10 04:01:15 +00:00
|
|
|
reader.forEach(function(entry) {
|
|
|
|
var Name = entry.getName();
|
2019-07-10 07:59:04 +00:00
|
|
|
var Path = global.GetCodePath(Name);
|
2019-07-10 04:01:15 +00:00
|
|
|
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 {
|
2019-07-10 07:59:04 +00:00
|
|
|
global.StopChildProcess();
|
2019-07-10 04:01:15 +00:00
|
|
|
global.ToLog("********************************** FORCE RESTART!!!");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (this.ActualNodes) {
|
|
|
|
var it = this.ActualNodes.iterator(), Node;
|
|
|
|
while ((Node = it.next()) !== null) {
|
|
|
|
if (Node.Socket)
|
2019-07-10 07:59:04 +00:00
|
|
|
global.CloseSocket(Node.Socket, "Restart");
|
2019-07-10 04:01:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
this.StopServer();
|
|
|
|
this.StopNode();
|
2019-07-10 07:59:04 +00:00
|
|
|
global.StopChildProcess();
|
2019-07-10 04:01:15 +00:00
|
|
|
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';
|
2019-07-10 07:59:04 +00:00
|
|
|
global.SaveToFile("run-next.bat", StrRun);
|
2019-07-10 04:01:15 +00:00
|
|
|
const child_process = require('child_process');
|
|
|
|
child_process.exec("run-next.bat", { shell: true });
|
|
|
|
}
|
|
|
|
global.ToLog("EXIT 3");
|
|
|
|
process.exit(0);
|
|
|
|
};
|