0.1007
parent
b4a083b40d
commit
43d2ed18b3
Binary file not shown.
Binary file not shown.
|
@ -1218,10 +1218,10 @@
|
|||
"Sign JSON": "Подписать JSON",
|
||||
"Send from JSON": "Отправить JSON",
|
||||
|
||||
"ACCOUNTS": "СЧЕТА",
|
||||
"SEND": "ОТПРАВКА",
|
||||
"DAPPS": "ПРИЛОЖЕНИЯ",
|
||||
"EXPLORER": "ЭКСПЛОРЕР",
|
||||
"ACCOUNTS": "Счета",
|
||||
"SEND": "Отправка",
|
||||
"DAPPS": "Приложения",
|
||||
"EXPLORER": "Эксплорер",
|
||||
"ID": "ИД",
|
||||
"Amount": "Сумма",
|
||||
"Currency": "Валюта",
|
||||
|
@ -1258,63 +1258,62 @@
|
|||
};
|
||||
|
||||
LangMap["DEU"]=
|
||||
{
|
||||
"TERA Light": "TERA Light",
|
||||
"Wallet opened: ": "Wallet geöffnet: ",
|
||||
"Edit...": "Bearbeiten",
|
||||
"OK": "ОК",
|
||||
"Cancel": "Abbrechen",
|
||||
"Generate key": "Key erzeugen",
|
||||
" Reconnect": "Erneut verinden",
|
||||
" New account...": "Neuer ID",
|
||||
"Accounts": "Accounts",
|
||||
"Counters": "Zähler",
|
||||
"Send": "Senden",
|
||||
{
|
||||
"TERA Light": "TERA Light",
|
||||
"Wallet opened: ": "Wallet geöffnet: ",
|
||||
"Edit...": "Bearbeiten...",
|
||||
"OK": "ОК",
|
||||
"Cancel": "Abbr.",
|
||||
"Generate key": "Key erzeugen",
|
||||
" Reconnect": " Neu verbinden",
|
||||
" New account...": " Neuer ID...",
|
||||
"Accounts": "Accounts",
|
||||
"Counters": "Statistiken",
|
||||
"Send": "Senden",
|
||||
|
||||
"Clear": "Löschen",
|
||||
"Edit JSON": "JSON Bearbeten",
|
||||
"Sign JSON": "JSON Signieren",
|
||||
"Send from JSON": "Von JSON gesendet",
|
||||
"Clear": "Löschen",
|
||||
"Edit JSON": "JSON Bearbeten",
|
||||
"Sign JSON": "JSON Signieren",
|
||||
"Send from JSON": "Von JSON gesendet",
|
||||
|
||||
"ACCOUNTS": "Accounts",
|
||||
"SEND": "Senden",
|
||||
"DAPPS": "DApps",
|
||||
"EXPLORER": "Explorer",
|
||||
"ID": "ID",
|
||||
"Amount": "Summe",
|
||||
"Currency": "Währung",
|
||||
"Name": "Name",
|
||||
"Smart": "Zugeordnete DApp",
|
||||
"Description": "Beschreibung",
|
||||
"Category": "Kategorie",
|
||||
"Base Account": "Standard Account",
|
||||
"Owner": "Besitzer",
|
||||
"Token generate": "Token generieren",
|
||||
"Block Num": "Block Nummer",
|
||||
"Cur": "Währung",
|
||||
"PubKey": "Öffentlicher Schlüssel",
|
||||
"Operation": "Transaktionen",
|
||||
"Num": "Nr",
|
||||
"Date": "Datum",
|
||||
"Data Hash": "Hashwert",
|
||||
"PowHash": "PoW Hash",
|
||||
"Block Hash": "Block Hash",
|
||||
"Bytes": "Bytes",
|
||||
"Pow": "Pow",
|
||||
"Miner": "Miner",
|
||||
"Wallet:": "Wallet:",
|
||||
"Private key:": "Privater Schlüssel:",
|
||||
"Pub key:": "Öffentlicher Schlüssel:",
|
||||
"From account": "Von Account",
|
||||
"Pay to": "Empfänger",
|
||||
"Description (optional)": "Beschreibung (optional)",
|
||||
"Public name":"Öffentl. Name",
|
||||
"Show pub key":"Zeige öffentlichen Schlüssel",
|
||||
"Blocks & Tr":"Blöcke & Tr",
|
||||
"<< Prev":"<< zurück",
|
||||
"Next >>":"weiter >>",
|
||||
"ACCOUNTS": "Accounts",
|
||||
"SEND": "Überweisung",
|
||||
"DAPPS": "DApps",
|
||||
"EXPLORER": "Explorer",
|
||||
"ID": "ID",
|
||||
"Amount": "Betrag",
|
||||
"Currency": "Währung",
|
||||
"Name": "Beschreibung",
|
||||
"Smart": "DApp ID",
|
||||
"Description": "Öffentl. Name",
|
||||
"Category": "Kategorie",
|
||||
"Base Account": "Standard Account",
|
||||
"Owner": "Besitzer",
|
||||
"Token generate": "Token generieren",
|
||||
"Block Num": "Block",
|
||||
"Cur": "Währung",
|
||||
"PubKey": "Öffentl. Schlüssel",
|
||||
"Operation": "Transaktionen",
|
||||
"Num": "Nr",
|
||||
"Date": "Datum",
|
||||
"Data Hash": "Hashwert",
|
||||
"PowHash": "PoW Hash",
|
||||
"Block Hash": "Block Hash",
|
||||
"Bytes": "Bytes",
|
||||
"Pow": "Pow",
|
||||
"Miner": "Miner",
|
||||
"Wallet:": "Wallet:",
|
||||
"Private key:": "Privater Schlüssel:",
|
||||
"Pub key:": "Öffentl. Schlüssel:",
|
||||
"From account": "Von Account",
|
||||
"Pay to": "Empfänger",
|
||||
"Description (optional)": "Beschreibung (optional)",
|
||||
"Public name":"Öffentl. Name",
|
||||
"Show pub key":"Zeige öffentlichen Schlüssel",
|
||||
"Blocks & Tr":"Blöcke & Tr",
|
||||
"<< Prev":"<< zurück",
|
||||
"Next >>":"weiter >>",
|
||||
};
|
||||
|
||||
LangMap[" 中文"]=
|
||||
{
|
||||
"TERA Light": "TERA轻钱包",
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
PrevEditContent[Name]=elem.innerHTML;
|
||||
var Path=EditMap[Name];
|
||||
if(Path)
|
||||
GetData("/GetFileContent",{Path:Path,Password:GetPassword()},function (Data)
|
||||
GetDataWebEdit("/GetFileContent",{Path:Path,Password:GetPassword()},function (Data)
|
||||
{
|
||||
//console.log("result="+JSON.stringify(Data));
|
||||
elem.innerText=Data.Body;
|
||||
|
@ -62,7 +62,7 @@
|
|||
var elem2=ByID("Edit"+Name);
|
||||
var Path=EditMap[Name];
|
||||
if(Path)
|
||||
GetData("/SaveFileContent",{Path:Path,Password:GetPassword(),Body:elem2.innerText},function (Data)
|
||||
GetDataWebEdit("/SaveFileContent",{Path:Path,Password:GetPassword(),Body:elem2.innerText},function (Data)
|
||||
{
|
||||
if(Data.result)
|
||||
//PrevEditContent[Name]=GetToolbarHTML(Name)+Data.Body;
|
||||
|
@ -90,7 +90,7 @@
|
|||
{
|
||||
return document.getElementById(id);
|
||||
}
|
||||
function GetData(Method, ObjPost, Func)
|
||||
function GetDataWebEdit(Method, ObjPost, Func)
|
||||
{
|
||||
//console.log(Method);
|
||||
var serv=new XMLHttpRequest();
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
|
||||
function UpdatesConfigData(bFirst)
|
||||
{
|
||||
window.MainServer=undefined;
|
||||
|
||||
GetData("GetCurrentInfo",{Diagram:IsVisibleBlock("idStatBlock")?1:0}, function (Data)
|
||||
{
|
||||
SetConfigData(Data,bFirst);
|
||||
|
@ -75,6 +77,8 @@
|
|||
SetDiagramMouseX(event);
|
||||
}
|
||||
|
||||
delete localStorage["MainServer"];
|
||||
|
||||
};
|
||||
</script>
|
||||
|
||||
|
|
|
@ -1492,16 +1492,19 @@ module.exports = class CConsensus extends require("./block-loader")
|
|||
}
|
||||
}
|
||||
}
|
||||
for(var BlockNum = CURRENTBLOCKNUM - BLOCK_PROCESSING_LENGTH2; BlockNum > BLOCK_PROCESSING_LENGTH2 && BlockNum < start_save; BlockNum++)
|
||||
{
|
||||
var Block = this.GetBlock(BlockNum);
|
||||
if(Block && !Block.bSave && Block.TrCount && Block.TreeHash && !IsZeroArr(Block.TreeHash) && !Block.WasSaveDataTree)
|
||||
var MaxNumBlockDB = this.GetMaxNumBlockDB();
|
||||
if(CURRENTBLOCKNUM + BLOCK_PROCESSING_LENGTH2 > MaxNumBlockDB)
|
||||
for(var BlockNum = CURRENTBLOCKNUM - BLOCK_PROCESSING_LENGTH2; BlockNum > BLOCK_PROCESSING_LENGTH2 && BlockNum < start_save; BlockNum++)
|
||||
{
|
||||
this.SaveDataTreeToDB(Block)
|
||||
Block.WasSaveDataTree = 1
|
||||
AddInfoBlock(Block, "*SAVE DATA TREE*")
|
||||
var Block = this.GetBlock(BlockNum);
|
||||
if(Block && !Block.bSave && Block.TrCount && Block.TreeHash && !IsZeroArr(Block.TreeHash) && !Block.WasSaveDataTree)
|
||||
{
|
||||
this.PreSaveDataTreeToDB(Block)
|
||||
Block.WasSaveDataTree = 1
|
||||
AddInfoBlock(Block, "*PRESAVE DATA TREE*")
|
||||
ToLog("PRESAVE DATA: " + Block.BlockNum)
|
||||
}
|
||||
}
|
||||
}
|
||||
this.RelayMode = !bWasSave
|
||||
this.FREE_MEM_BLOCKS(CURRENTBLOCKNUM - BLOCK_COUNT_IN_MEMORY)
|
||||
}
|
||||
|
|
|
@ -1445,7 +1445,7 @@ global.LoadBlockFromNetwork = function (Params,F)
|
|||
F(1);
|
||||
return ;
|
||||
}
|
||||
ToLog("DownloadBlockFromNetwork:" + BlockNum, 2);
|
||||
ToLog("Start DownloadBlockFromNetwork:" + BlockNum, 2);
|
||||
var TaskLoadBlockFromNetwork = {MapSend:{}};
|
||||
var Ret = SERVER.GetNextNode(TaskLoadBlockFromNetwork, BlockNum, 1);
|
||||
if(Ret.Result)
|
||||
|
@ -1461,7 +1461,7 @@ global.LoadBlockFromNetwork = function (Params,F)
|
|||
F(1);
|
||||
return ;
|
||||
}
|
||||
ToLog("Got BlockFromNetwork:" + BlockNum, 2);
|
||||
ToLog("Got BlockFromNetwork:" + BlockNum + " from " + NodeName(Info.Node), 2);
|
||||
SERVER.WriteBlockDB(Block);
|
||||
F(0, Block);
|
||||
}}, });
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
||||
*/
|
||||
|
||||
global.UPDATE_CODE_VERSION_NUM = 1003;
|
||||
global.UPDATE_CODE_VERSION_NUM = 1007;
|
||||
global.MIN_CODE_VERSION_NUM = 992;
|
||||
global.MINING_VERSION_NUM = 3;
|
||||
global.InitParamsArg = InitParamsArg;
|
||||
|
@ -19,7 +19,8 @@ global.CONST_NAME_ARR = ["AUTO_CORRECT_TIME", "DELTA_CURRENT_TIME", "COMMON_KEY"
|
|||
"USE_AUTO_UPDATE", "RESTART_PERIOD_SEC", "MAX_GRAY_CONNECTIONS_TO_SERVER", "TRANSACTION_PROOF_COUNT", "UPDATE_NUM_COMPLETE",
|
||||
"LIMIT_SEND_TRAFIC", "WATCHDOG_DEV", "ADDRLIST_MODE", "CheckPointDelta", "MIN_VER_STAT", "DEBUG_WALLET", "HTTP_HOSTING_PORT",
|
||||
"HTTPS_HOSTING_DOMAIN", "HTTP_MAX_COUNT_ROWS", "HTTP_ADMIN_PASSORD", "WATCHDOG_BADACCOUNT", "RESYNC_CONDITION", "MAX_CONNECTIONS_COUNT",
|
||||
"TRUST_PROCESS_COUNT", "REST_START_COUNT", ];
|
||||
"TRUST_PROCESS_COUNT", "REST_START_COUNT", "DB_VERSION", ];
|
||||
global.DB_VERSION = 1;
|
||||
global.USE_HARD_API_V2 = 0;
|
||||
global.USE_TICKET = 0;
|
||||
global.USE_CHECK_SENDING = 1;
|
||||
|
|
|
@ -15,6 +15,22 @@ global.BlockDB = new DBLib();
|
|||
global.BLOCK_HEADER_SIZE = 150;
|
||||
const FILE_NAME_HEADER = "block-header";
|
||||
const FILE_NAME_BODY = "block-body";
|
||||
const FORMAT_STREAM_HEADER = "{\
|
||||
VersionDB:byte,\
|
||||
TreeHash:hash,\
|
||||
AddrHash:hash,\
|
||||
PrevHash:hash,\
|
||||
SumHash:hash,\
|
||||
SumPow:uint,\
|
||||
TrDataPos:uint,\
|
||||
TrDataLen:uint32,\
|
||||
Reserv500:uint\
|
||||
}";
|
||||
const WorkStructStreamHeader = {};
|
||||
global.BLOCK_HEADER_SIZE2 = 6;
|
||||
const FORMAT_HEADER_VERSION2 = "{FilePos:uint}";
|
||||
const FILE_NAME_HEADER2 = "block-header2";
|
||||
const WorkStructHeader2 = {};
|
||||
module.exports = class CDB extends require("../code")
|
||||
{
|
||||
constructor(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
||||
|
@ -22,10 +38,23 @@ module.exports = class CDB extends require("../code")
|
|||
super(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
||||
var bWriteMode = (global.PROCESS_NAME === "MAIN");
|
||||
BlockDB.OpenDBFile(FILE_NAME_HEADER, bWriteMode)
|
||||
BlockDB.OpenDBFile(FILE_NAME_HEADER2, bWriteMode)
|
||||
BlockDB.OpenDBFile(FILE_NAME_BODY, bWriteMode)
|
||||
this.BlockNumDB = 0
|
||||
this.BlockNumDBMin = 0
|
||||
this.ClearBufMap()
|
||||
setTimeout(function ()
|
||||
{
|
||||
SERVER.ReadStateTX()
|
||||
}, 10)
|
||||
}
|
||||
ReadStateTX()
|
||||
{
|
||||
var StateTX = DApps.Accounts.DBStateTX.Read(0);
|
||||
if(StateTX)
|
||||
{
|
||||
this.BlockNumDBMin = StateTX.BlockNumMin
|
||||
}
|
||||
}
|
||||
LoadMemBlocksOnStart()
|
||||
{
|
||||
|
@ -41,18 +70,22 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
GetMaxNumBlockDB()
|
||||
{
|
||||
var FI = BlockDB.OpenDBFile(FILE_NAME_HEADER);
|
||||
var BlockNum = (FI.size / BLOCK_HEADER_SIZE) - 1;
|
||||
var FileItem, BlockNum;
|
||||
if(global.DB_VERSION === 2)
|
||||
{
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER2)
|
||||
BlockNum = (FileItem.size / BLOCK_HEADER_SIZE2) - 1
|
||||
}
|
||||
else
|
||||
{
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER)
|
||||
BlockNum = (FileItem.size / BLOCK_HEADER_SIZE) - 1
|
||||
}
|
||||
return BlockNum;
|
||||
}
|
||||
FindStartBlockNum()
|
||||
{
|
||||
var StateTX = DApps.Accounts.DBStateTX.Read(0);
|
||||
if(StateTX)
|
||||
{
|
||||
this.BlockNumDBMin = StateTX.BlockNumMin
|
||||
}
|
||||
ToLog("BlockNumDBMin=" + this.BlockNumDBMin, 2)
|
||||
this.ReadStateTX()
|
||||
var BlockNum = this.GetMaxNumBlockDB();
|
||||
if(global.NO_CHECK_BLOCKNUM_ONSTART)
|
||||
{
|
||||
|
@ -206,14 +239,12 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
return Ret;
|
||||
}
|
||||
SaveDataTreeToDB(Block)
|
||||
PreSaveDataTreeToDB(Block)
|
||||
{
|
||||
var Ret = this.WriteBodyDB(Block);
|
||||
if(Ret)
|
||||
{
|
||||
var BufWrite = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE);
|
||||
this.BlockHeaderToBuf(BufWrite, Block)
|
||||
Ret = this.WriteBufHeaderDB(BufWrite, Block.BlockNum)
|
||||
Ret = this.WriteBlockHeaderDB(Block, 1)
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
@ -287,9 +318,9 @@ module.exports = class CDB extends require("../code")
|
|||
Block.TrDataLen = TrDataLen
|
||||
return true;
|
||||
}
|
||||
WriteBlockHeaderDB(Block)
|
||||
WriteBlockHeaderDB(Block, bPreSave)
|
||||
{
|
||||
if(Block.BlockNum > this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
if(!bPreSave && Block.BlockNum > this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
{
|
||||
if(USE_CHECK_SAVE_DB)
|
||||
if(!this.CheckSeqHashDB(Block, "WriteBlockHeaderDB"))
|
||||
|
@ -306,29 +337,71 @@ module.exports = class CDB extends require("../code")
|
|||
Block.SumHash = shaarr2(PrevBlock.SumHash, Block.Hash)
|
||||
Block.SumPow = PrevBlock.SumPow + GetPowPower(Block.PowHash)
|
||||
}
|
||||
else
|
||||
if(global.DB_VERSION === 2)
|
||||
{
|
||||
var Stop = 1;
|
||||
return this.WriteBlockHeaderToFile2(Block);
|
||||
}
|
||||
var BufWrite = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE);
|
||||
this.BlockHeaderToBuf(BufWrite, Block)
|
||||
var Res = this.WriteBufHeaderDB(BufWrite, Block.BlockNum);
|
||||
var Res = this.WriteBufHeaderToFile1(BufWrite, Block.BlockNum);
|
||||
return Res;
|
||||
}
|
||||
WriteBufHeaderDB(BufWrite, BlockNum)
|
||||
WriteBlockHeaderToFile2(Block)
|
||||
{
|
||||
BlockNum = Math.trunc(BlockNum)
|
||||
var BufWrite, FileItem, written;
|
||||
var BlockNum = Math.trunc(Block.BlockNum);
|
||||
this.ClearBufMap()
|
||||
var Position = BlockNum * BLOCK_HEADER_SIZE;
|
||||
var FI = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1);
|
||||
var written = fs.writeSync(FI.fd, BufWrite, 0, BufWrite.length, Position);
|
||||
if(Position >= FI.size)
|
||||
Block.VersionDB = global.DB_VERSION
|
||||
BufWrite = BufLib.GetBufferFromObject(Block, FORMAT_STREAM_HEADER, 200, WorkStructStreamHeader)
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_BODY, 1)
|
||||
if(!Block.FilePos)
|
||||
{
|
||||
FI.size = Position + BufWrite.length
|
||||
if(!FileItem.size)
|
||||
FileItem.size = 100
|
||||
Block.FilePos = FileItem.size
|
||||
}
|
||||
written = fs.writeSync(FileItem.fd, BufWrite, 0, BufWrite.length, Block.FilePos)
|
||||
if(written !== BufWrite.length)
|
||||
{
|
||||
TO_ERROR_LOG("DB", 242, "Error write to file block-chain : " + written + " <> " + BufWrite.length)
|
||||
return false;
|
||||
}
|
||||
if(Block.FilePos >= FileItem.size)
|
||||
{
|
||||
FileItem.size = Block.FilePos + BufWrite.length
|
||||
}
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER2, 1)
|
||||
var Position = BlockNum * BLOCK_HEADER_SIZE2;
|
||||
BufWrite = BufLib.GetBufferFromObject(Block, FORMAT_HEADER_VERSION2, BLOCK_HEADER_SIZE2, WorkStructHeader2)
|
||||
written = fs.writeSync(FileItem.fd, BufWrite, 0, BufWrite.length, Position)
|
||||
if(Position >= FileItem.size)
|
||||
{
|
||||
FileItem.size = Position + BufWrite.length
|
||||
}
|
||||
if(written !== BufWrite.length)
|
||||
{
|
||||
TO_ERROR_LOG("DB", 260, "Error write to file block-header :" + written + " <> " + Info.key_width)
|
||||
TO_ERROR_LOG("DB", 262, "Error write to file block-header :" + written + " <> " + BufWrite.length)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
WriteBufHeaderToFile1(BufWrite, BlockNum)
|
||||
{
|
||||
BlockNum = Math.trunc(BlockNum)
|
||||
this.ClearBufMap()
|
||||
var FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1);
|
||||
var Position = BlockNum * BLOCK_HEADER_SIZE;
|
||||
var written = fs.writeSync(FileItem.fd, BufWrite, 0, BufWrite.length, Position);
|
||||
if(Position >= FileItem.size)
|
||||
{
|
||||
FileItem.size = Position + BufWrite.length
|
||||
}
|
||||
if(written !== BufWrite.length)
|
||||
{
|
||||
TO_ERROR_LOG("DB", 260, "Error write to file block-header :" + written + " <> " + BufWrite.length)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -361,7 +434,6 @@ module.exports = class CDB extends require("../code")
|
|||
ReadBlockBodyDB(Block)
|
||||
{
|
||||
var FileItem = BlockDB.OpenDBFile(FILE_NAME_BODY);
|
||||
var FD = FileItem.fd;
|
||||
if(Block.TrDataLen > MAX_BLOCK_SIZE * 2)
|
||||
{
|
||||
ToLogTrace("Error value TrDataLen, BlockNum=" + Block.BlockNum)
|
||||
|
@ -369,7 +441,7 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
var Position = Block.TrDataPos;
|
||||
var BufRead = BufLib.GetNewBuffer(Block.TrDataLen);
|
||||
var bytesRead = fs.readSync(FD, BufRead, 0, BufRead.length, Position);
|
||||
var bytesRead = fs.readSync(FileItem.fd, BufRead, 0, BufRead.length, Position);
|
||||
if(bytesRead !== BufRead.length)
|
||||
{
|
||||
TO_ERROR_LOG("DB", 272, "Error read block-body file: " + FileItem.name + " from POS:" + Position + " bytesRead=" + bytesRead + " of " + BufRead.length + " BlockNum=" + Block.BlockNum)
|
||||
|
@ -401,20 +473,25 @@ module.exports = class CDB extends require("../code")
|
|||
Block.TrCount = Block.arrContent.length
|
||||
return true;
|
||||
}
|
||||
ReadBlockHeaderDB(Num)
|
||||
ReadBlockHeaderDB(BlockNum)
|
||||
{
|
||||
if(Num < 0)
|
||||
if(global.DB_VERSION === 2)
|
||||
{
|
||||
return this.ReadBlockHeaderDB2(BlockNum);
|
||||
}
|
||||
if(BlockNum < 0)
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
Num = Math.trunc(Num)
|
||||
var BufRead = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE);
|
||||
var Position = Num * BLOCK_HEADER_SIZE;
|
||||
var FD = BlockDB.OpenDBFile(FILE_NAME_HEADER).fd;
|
||||
var bytesRead = fs.readSync(FD, BufRead, 0, BufRead.length, Position);
|
||||
BlockNum = Math.trunc(BlockNum)
|
||||
var Block, BufRead, FileItem, bytesRead, Position;
|
||||
BufRead = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE)
|
||||
Position = BlockNum * BLOCK_HEADER_SIZE
|
||||
var FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER);
|
||||
bytesRead = fs.readSync(FileItem.fd, BufRead, 0, BufRead.length, Position)
|
||||
if(bytesRead !== BufRead.length)
|
||||
return undefined;
|
||||
var Block = this.BufToBlockHeader(BufRead, Num);
|
||||
Block = this.BufToBlockHeader(BufRead, BlockNum)
|
||||
if(Block)
|
||||
{
|
||||
Block.bSave = true
|
||||
|
@ -422,29 +499,64 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
return Block;
|
||||
}
|
||||
ReadBlockHeaderFromMapDB(Num)
|
||||
ReadBlockHeaderDB2(BlockNum)
|
||||
{
|
||||
var Block = this.MapHeader[Num];
|
||||
var Block, BufRead, FileItem, bytesRead, Position;
|
||||
if(BlockNum < 0)
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
BlockNum = Math.trunc(BlockNum)
|
||||
Position = BlockNum * BLOCK_HEADER_SIZE2
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_HEADER2)
|
||||
BufRead = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE2)
|
||||
bytesRead = fs.readSync(FileItem.fd, BufRead, 0, BufRead.length, Position)
|
||||
if(bytesRead !== BufRead.length)
|
||||
return undefined;
|
||||
Block = BufLib.GetObjectFromBuffer(BufRead, FORMAT_HEADER_VERSION2, WorkStructHeader2)
|
||||
if(!Block.FilePos)
|
||||
{
|
||||
return undefined;
|
||||
}
|
||||
Position = Block.FilePos
|
||||
FileItem = BlockDB.OpenDBFile(FILE_NAME_BODY)
|
||||
BufRead = BufLib.GetNewBuffer(200)
|
||||
bytesRead = fs.readSync(FileItem.fd, BufRead, 0, BufRead.length, Position)
|
||||
Block = BufLib.GetObjectFromBuffer(BufRead, FORMAT_STREAM_HEADER, WorkStructStreamHeader)
|
||||
if(Block.VersionDB !== global.DB_VERSION)
|
||||
{
|
||||
throw ("ERROR Block.VersionDB");
|
||||
return undefined;
|
||||
}
|
||||
Block.FilePos = Position
|
||||
Block.VersionDB = global.DB_VERSION
|
||||
Block.bSave = true
|
||||
Block.Prepared = true
|
||||
return this.PrepareBlockFields(Block, BlockNum);
|
||||
}
|
||||
ReadBlockHeaderFromMapDB(BlockNum)
|
||||
{
|
||||
var Block = this.MapHeader[BlockNum];
|
||||
if(!Block)
|
||||
{
|
||||
Block = this.ReadBlockHeaderDB(Num)
|
||||
this.MapHeader[Num] = Block
|
||||
Block = this.ReadBlockHeaderDB(BlockNum)
|
||||
this.MapHeader[BlockNum] = Block
|
||||
}
|
||||
return Block;
|
||||
}
|
||||
SetTruncateBlockDB(Num)
|
||||
SetTruncateBlockDB(BlockNum)
|
||||
{
|
||||
Num = Math.trunc(Num)
|
||||
if(Num < BLOCK_PROCESSING_LENGTH2)
|
||||
Num = BLOCK_PROCESSING_LENGTH2
|
||||
BlockNum = Math.trunc(BlockNum)
|
||||
if(BlockNum < BLOCK_PROCESSING_LENGTH2)
|
||||
BlockNum = BLOCK_PROCESSING_LENGTH2
|
||||
if(this.UseTruncateBlockDB)
|
||||
{
|
||||
if(Num < this.UseTruncateBlockDB)
|
||||
this.UseTruncateBlockDB = Num
|
||||
if(BlockNum < this.UseTruncateBlockDB)
|
||||
this.UseTruncateBlockDB = BlockNum
|
||||
}
|
||||
else
|
||||
{
|
||||
this.UseTruncateBlockDB = Num
|
||||
this.UseTruncateBlockDB = BlockNum
|
||||
}
|
||||
}
|
||||
TruncateBlockDB(LastBlockNum)
|
||||
|
@ -460,8 +572,17 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
TruncateBlockDBInner(LastBlock)
|
||||
{
|
||||
var FItem1 = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1);
|
||||
var size = (LastBlock.BlockNum + 1) * BLOCK_HEADER_SIZE;
|
||||
var FItem1, size;
|
||||
if(global.DB_VERSION === 2)
|
||||
{
|
||||
FItem1 = BlockDB.OpenDBFile(FILE_NAME_HEADER2, 1)
|
||||
size = (LastBlock.BlockNum + 1) * BLOCK_HEADER_SIZE2
|
||||
}
|
||||
else
|
||||
{
|
||||
FItem1 = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1)
|
||||
size = (LastBlock.BlockNum + 1) * BLOCK_HEADER_SIZE
|
||||
}
|
||||
if(size < 0)
|
||||
size = 0
|
||||
if(FItem1.size > size)
|
||||
|
@ -471,34 +592,6 @@ module.exports = class CDB extends require("../code")
|
|||
}
|
||||
this.TruncateStat(LastBlock.BlockNum)
|
||||
}
|
||||
TruncateBlockBodyDBInner()
|
||||
{
|
||||
var FItem2 = BlockDB.OpenDBFile(FILE_NAME_BODY, 1);
|
||||
var size2 = 0;
|
||||
if(FItem2.size !== size2)
|
||||
{
|
||||
this.ClearBufMap()
|
||||
FItem2.size = size2
|
||||
fs.ftruncateSync(FItem2.fd, FItem2.size)
|
||||
}
|
||||
}
|
||||
TruncateFileBuf(Tree, size)
|
||||
{
|
||||
while(true)
|
||||
{
|
||||
var Item = Tree.max();
|
||||
if(Item === null)
|
||||
break;
|
||||
if(Item.Position >= size)
|
||||
{
|
||||
Tree.remove(Item)
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ClearDataBase()
|
||||
{
|
||||
if(global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
||||
|
@ -506,6 +599,9 @@ module.exports = class CDB extends require("../code")
|
|||
var FItem1 = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1);
|
||||
FItem1.size = 0
|
||||
fs.ftruncateSync(FItem1.fd, FItem1.size)
|
||||
var FItem12 = BlockDB.OpenDBFile(FILE_NAME_HEADER2, 1);
|
||||
FItem12.size = 0
|
||||
fs.ftruncateSync(FItem12.fd, FItem12.size)
|
||||
var FItem2 = BlockDB.OpenDBFile(FILE_NAME_BODY, 1);
|
||||
FItem2.size = 0
|
||||
fs.ftruncateSync(FItem2.fd, FItem2.size)
|
||||
|
@ -520,6 +616,14 @@ module.exports = class CDB extends require("../code")
|
|||
{
|
||||
this.MapHeader = {}
|
||||
}
|
||||
Close()
|
||||
{
|
||||
this.ClearBufMap()
|
||||
this.ReadStateTX()
|
||||
BlockDB.CloseDBFile(FILE_NAME_HEADER)
|
||||
BlockDB.CloseDBFile(FILE_NAME_HEADER2)
|
||||
BlockDB.CloseDBFile(FILE_NAME_BODY)
|
||||
}
|
||||
RewriteAllTransactions()
|
||||
{
|
||||
if(TX_PROCESS.Worker)
|
||||
|
@ -549,8 +653,6 @@ module.exports = class CDB extends require("../code")
|
|||
BufToBlockHeader(BufRead, Num)
|
||||
{
|
||||
var Block = {};
|
||||
Block.AddInfo = AddInfoBlock.bind(Block)
|
||||
Block.Info = ""
|
||||
var len = BufRead.len;
|
||||
Block.TreeHash = BufRead.Read("hash")
|
||||
Block.AddrHash = BufRead.Read("hash")
|
||||
|
@ -562,6 +664,12 @@ module.exports = class CDB extends require("../code")
|
|||
Block.TrDataLen = BufRead.Read("uint32")
|
||||
Block.TrCount = 0
|
||||
BufRead.len = len + BLOCK_HEADER_SIZE
|
||||
return this.PrepareBlockFields(Block, Num);
|
||||
}
|
||||
PrepareBlockFields(Block, Num)
|
||||
{
|
||||
Block.AddInfo = AddInfoBlock.bind(Block)
|
||||
Block.Info = ""
|
||||
Block.BlockNum = Num
|
||||
Block.SeqHash = this.GetSeqHash(Block.BlockNum, Block.PrevHash, Block.TreeHash)
|
||||
if(Block.BlockNum >= BLOCK_PROCESSING_LENGTH2)
|
||||
|
@ -652,7 +760,10 @@ module.exports = class CDB extends require("../code")
|
|||
if(App)
|
||||
{
|
||||
Tr.Script = App.GetScriptTransaction(Tr.body)
|
||||
Tr.Verify = App.GetVerifyTransaction(Block, BlockNum, Tr.Num, Tr.body)
|
||||
if(BlockNum >= this.BlockNumDBMin)
|
||||
Tr.Verify = App.GetVerifyTransaction(Block, BlockNum, Tr.Num, Tr.body)
|
||||
else
|
||||
Tr.Verify = 0
|
||||
if(Tr.Verify >= 1)
|
||||
{
|
||||
Tr.VerifyHTML = "<B style='color:green'>✔</B>"
|
||||
|
|
|
@ -437,15 +437,16 @@ HTTPCaller.DappSmartList = function (Params)
|
|||
var arr = DApps.Smart.GetRows(Params.StartNum, Params.CountNum, undefined, undefined, Params.GetAllData, Params.TokenGenerate);
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HTTPCaller.DappBlockList = function (Params)
|
||||
HTTPCaller.DappBlockList = function (Params,response)
|
||||
{
|
||||
var arr = SERVER.GetRows(Params.StartNum, Params.CountNum);
|
||||
return {arr:arr, result:1};
|
||||
Params.Filter = undefined;
|
||||
return HTTPCaller.GetBlockList(Params, response);
|
||||
};
|
||||
HTTPCaller.DappTransactionList = function (Params)
|
||||
HTTPCaller.DappTransactionList = function (Params,response)
|
||||
{
|
||||
var arr = SERVER.GetTrRows(Params.BlockNum, Params.StartNum, Params.CountNum);
|
||||
return {arr:arr, result:1};
|
||||
Params.Filter = undefined;
|
||||
Params.Param3 = Params.BlockNum;
|
||||
return HTTPCaller.GetTransactionAll(Params, response);
|
||||
};
|
||||
var sessionid = GetHexFromAddres(crypto.randomBytes(20));
|
||||
HTTPCaller.RestartNode = function (Params)
|
||||
|
@ -483,18 +484,68 @@ HTTPCaller.GetDappList = function (Params)
|
|||
var arr = DApps.Smart.GetRows(Params.StartNum, Params.CountNum, Params.Filter, Params.Filter2);
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HTTPCaller.GetBlockList = function (Params)
|
||||
HTTPCaller.GetBlockList = function (Params,response)
|
||||
{
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
if(Params.StartNum < SERVER.BlockNumDBMin)
|
||||
{
|
||||
let CountWait = 0;
|
||||
var WasWait = 0;
|
||||
for(var BlockNum = Params.StartNum; BlockNum < Params.StartNum + Params.CountNum; BlockNum++)
|
||||
{
|
||||
var Block = SERVER.ReadBlockHeaderDB(BlockNum);
|
||||
if(!Block)
|
||||
{
|
||||
CountWait++;
|
||||
WasWait = 1;
|
||||
LoadBlockFromNetwork({BlockNum:BlockNum}, function (Err,Block)
|
||||
{
|
||||
CountWait--;
|
||||
if(CountWait === 0)
|
||||
{
|
||||
var arr = SERVER.GetRows(Params.StartNum, Params.CountNum, Params.Filter);
|
||||
var Result = {arr:arr, result:1};
|
||||
response.end(JSON.stringify(Result));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if(WasWait)
|
||||
return null;
|
||||
}
|
||||
var arr = SERVER.GetRows(Params.StartNum, Params.CountNum, Params.Filter);
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HTTPCaller.GetTransactionAll = function (Params)
|
||||
HTTPCaller.GetTransactionAll = function (Params,response)
|
||||
{
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
var arr = SERVER.GetTrRows(Params.Param3, Params.StartNum, Params.CountNum, Params.Filter);
|
||||
var BlockNum = Params.Param3;
|
||||
if(BlockNum < SERVER.BlockNumDBMin)
|
||||
{
|
||||
var Block = SERVER.ReadBlockHeaderDB(BlockNum);
|
||||
if(!Block)
|
||||
{
|
||||
LoadBlockFromNetwork({BlockNum:BlockNum}, function (Err,Block)
|
||||
{
|
||||
var Result;
|
||||
if(Err)
|
||||
{
|
||||
Result = {arr:[], result:0};
|
||||
}
|
||||
else
|
||||
{
|
||||
var arr = 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 = SERVER.GetTrRows(BlockNum, Params.StartNum, Params.CountNum, Params.Filter);
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HTTPCaller.GetActList = function (Params)
|
||||
|
|
|
@ -170,11 +170,11 @@ class AccountApp extends require("./dapp")
|
|||
this.DBStateHistory = new DBRow("history-state", 8, this.FORMAT_STATE_HISTORY, bReadOnly)
|
||||
HistoryDB.OpenDBFile(FILE_NAME_HISTORY, !bReadOnly)
|
||||
this.HistoryFormatArr = ["{Type:byte, BlockNum:uint32,TrNum:uint16, NextPos:uint}", "{Type:byte, BlockNum:uint32,TrNum:uint16, NextPos:uint, Direct:str1,CorrID:uint, SumCOIN:uint,SumCENT:uint32}"]
|
||||
this.DBStateTX = new DBRow("accounts-tx", 6 + 6 + 88, "{BlockNum:uint, BlockNumMin:uint, Reserve: arr88}", bReadOnly)
|
||||
if(global.READ_ONLY_DB)
|
||||
return ;
|
||||
this.DBAccountsHash = new DBRow("accounts-hash3", 6 + 32 + 32 + 32 + 6 + 6 + 14, "{BlockNum:uint, AccHash:hash, SumHash:hash, SmartHash:hash, AccountMax:uint, SmartCount:uint, Reserve: arr14}",
|
||||
bReadOnly)
|
||||
this.DBStateTX = new DBRow("accounts-tx", 6 + 6 + 88, "{BlockNum:uint, BlockNumMin:uint, Reserve: arr88}", bReadOnly)
|
||||
if(global.START_SERVER)
|
||||
return ;
|
||||
if(!bReadOnly)
|
||||
|
|
|
@ -107,11 +107,9 @@ global.HTTP_PORT_NUMBER = 0;
|
|||
setInterval(function ()
|
||||
{
|
||||
if(SERVER)
|
||||
SERVER.ClearBufMap();
|
||||
SERVER.Close();
|
||||
DApps.Accounts.Close();
|
||||
DApps.Smart.DBSmart.Close();
|
||||
global.BlockDB.CloseDBFile("block-header");
|
||||
global.BlockDB.CloseDBFile("block-body");
|
||||
}, 1000);
|
||||
|
||||
function GETBLOCKHEADER(msg)
|
||||
|
|
|
@ -110,9 +110,9 @@ global.TreeFindTX = new STreeBuffer(30 * 1000, CompareItemHashSimple, "string");
|
|||
setInterval(function ()
|
||||
{
|
||||
if(SERVER)
|
||||
SERVER.ClearBufMap();
|
||||
global.BlockDB.CloseDBFile("block-header");
|
||||
global.BlockDB.CloseDBFile("block-body");
|
||||
{
|
||||
SERVER.Close();
|
||||
}
|
||||
DoTXProcess();
|
||||
}, 10);
|
||||
var BlockTree = new STreeBuffer(30 * 1000, CompareItemHashSimple, "number");
|
||||
|
@ -177,11 +177,15 @@ function FindMinimal()
|
|||
var MaxNumBlockDB = SERVER.GetMaxNumBlockDB();
|
||||
if(MaxNumBlockDB && MaxNumBlockDB < LastBlockNum)
|
||||
{
|
||||
if(bShowDetail)
|
||||
ToLog("MaxNumBlockDB<LastBlockNum: " + MaxNumBlockDB + "<" + LastBlockNum);
|
||||
LastBlockNum = MaxNumBlockDB - 1;
|
||||
BlockTree.Clear();
|
||||
}
|
||||
if(LastBlockNum < MinimalValidBlock)
|
||||
LastBlockNum = MinimalValidBlock;
|
||||
if(bShowDetail)
|
||||
ToLog("FindMinimal from LastBlockNum=" + LastBlockNum);
|
||||
for(var Num = LastBlockNum; Num--; Num >= 0)
|
||||
{
|
||||
if(Num < MinimalValidBlock)
|
||||
|
@ -211,8 +215,10 @@ function FindMinimal()
|
|||
}
|
||||
if(bShowDetail)
|
||||
ToLog("MinimalValidBlock:" + MinimalValidBlock);
|
||||
if(MinimalValidBlock === 0)
|
||||
if(MinimalValidBlock === 0 && LastBlockNum > 0)
|
||||
{
|
||||
RewriteAllTransactions();
|
||||
}
|
||||
Block = SERVER.ReadBlockHeaderDB(MinimalValidBlock);
|
||||
return Block;
|
||||
};
|
||||
|
|
|
@ -505,33 +505,32 @@ HostingCaller.GetAccount = function (id)
|
|||
var arr = DApps.Accounts.GetRowsAccounts(id, 1);
|
||||
return {Item:arr[0], result:1};
|
||||
};
|
||||
HostingCaller.GetBlockList = function (Params)
|
||||
HostingCaller.GetBlockList = function (Params,response)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
Params.StartNum = ParseNum(Params.StartNum);
|
||||
Params.CountNum = ParseNum(Params.CountNum);
|
||||
if(Params.CountNum > MaxCountViewRows)
|
||||
Params.CountNum = MaxCountViewRows;
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
var arr = SERVER.GetRows(ParseNum(Params.StartNum), ParseNum(Params.CountNum));
|
||||
return {result:1, arr:arr};
|
||||
return HTTPCaller.GetBlockList(Params, response);
|
||||
};
|
||||
HostingCaller.GetTransactionList = function (Params)
|
||||
HostingCaller.GetTransactionList = function (Params,response)
|
||||
{
|
||||
return HostingCaller.GetTransactionAll(Params);
|
||||
return HostingCaller.GetTransactionAll(Params, response);
|
||||
};
|
||||
HostingCaller.GetTransactionAll = function (Params)
|
||||
HostingCaller.GetTransactionAll = function (Params,response)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
Params.Param3 = ParseNum(Params.Param3);
|
||||
Params.StartNum = ParseNum(Params.StartNum);
|
||||
Params.CountNum = ParseNum(Params.CountNum);
|
||||
if(Params.CountNum > MaxCountViewRows)
|
||||
Params.CountNum = MaxCountViewRows;
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
if(Params.Param3)
|
||||
Params.BlockNum = Params.Param3;
|
||||
var arr = SERVER.GetTrRows(ParseNum(Params.BlockNum), ParseNum(Params.StartNum), ParseNum(Params.CountNum));
|
||||
return {result:1, arr:arr};
|
||||
return HTTPCaller.GetTransactionAll(Params, response);
|
||||
};
|
||||
HostingCaller.GetDappList = function (Params)
|
||||
{
|
||||
|
@ -748,27 +747,30 @@ HostingCaller.DappSmartList = function (Params)
|
|||
Params.TokenGenerate);
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HostingCaller.DappBlockList = function (Params)
|
||||
HostingCaller.DappBlockList = function (Params,response)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
Params.StartNum = ParseNum(Params.StartNum);
|
||||
Params.CountNum = ParseNum(Params.CountNum);
|
||||
if(Params.CountNum > MaxCountViewRows)
|
||||
Params.CountNum = MaxCountViewRows;
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
var arr = SERVER.GetRows(ParseNum(Params.StartNum), ParseNum(Params.CountNum));
|
||||
return {arr:arr, result:1};
|
||||
return HTTPCaller.DappBlockList(Params, response);
|
||||
};
|
||||
HostingCaller.DappTransactionList = function (Params)
|
||||
HostingCaller.DappTransactionList = function (Params,response)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
Params.BlockNum = ParseNum(Params.BlockNum);
|
||||
Params.StartNum = ParseNum(Params.StartNum);
|
||||
Params.CountNum = ParseNum(Params.CountNum);
|
||||
if(Params.CountNum > MaxCountViewRows)
|
||||
Params.CountNum = MaxCountViewRows;
|
||||
if(!Params.CountNum)
|
||||
Params.CountNum = 1;
|
||||
var arr = SERVER.GetTrRows(ParseNum(Params.BlockNum), ParseNum(Params.StartNum), ParseNum(Params.CountNum));
|
||||
return {arr:arr, result:1};
|
||||
return HTTPCaller.DappTransactionList(Params, response);
|
||||
};
|
||||
HostingCaller.DappStaticCall = function (Params,response)
|
||||
{
|
||||
|
@ -805,10 +807,10 @@ process.RunRPC = function (Name,Params,F)
|
|||
};
|
||||
setInterval(function ()
|
||||
{
|
||||
if(SERVER)
|
||||
SERVER.Close();
|
||||
DApps.Accounts.Close();
|
||||
DApps.Smart.DBSmart.Close();
|
||||
global.BlockDB.CloseDBFile("block-header");
|
||||
global.BlockDB.CloseDBFile("block-body");
|
||||
}, 500);
|
||||
setInterval(function ()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue