0.992
This commit is contained in:
parent
be1548fa14
commit
b70859c5a1
Binary file not shown.
Binary file not shown.
@ -2,6 +2,31 @@
|
||||
|
||||
This API is available if the node is running public http-access. Set the constant HTTP_HOSTING_PORT.
|
||||
|
||||
DappStaticCall - call static method
|
||||
Example (GET)
|
||||
```js
|
||||
http://dappsgate.com:88/api/v1/DappStaticCall?MethodName=Test&Account=540
|
||||
```
|
||||
|
||||
Example (POST)
|
||||
```js
|
||||
http://dappsgate.com:88/api/v1/DappStaticCall
|
||||
{
|
||||
"MethodName": "Test",
|
||||
"Account":540
|
||||
|
||||
}```
|
||||
|
||||
return value:
|
||||
```js
|
||||
{"result":1,"RetValue":"Test-ok"}
|
||||
```
|
||||
|
||||
see smart code of this example:
|
||||
http://dappsgate.com:88/smart/200
|
||||
|
||||
|
||||
|
||||
#### Getting the current status of the blockchain
|
||||
http://194.1.237.94/api/v1/GetCurrentInfo
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
# API v2 (for exchanges)
|
||||
Works with update version 0.901
|
||||
Works with update version 0.991
|
||||
|
||||
The API is designed to make it easier to write third-party applications. Server-side cryptography and POW operations are performed. Therefore, it is not recommended for public access, because it is not protected from DDOS attacks. Use it if applications such as the exchange server are on the same private network.
|
||||
|
||||
@ -12,6 +12,10 @@ This API is available if server is running http and hosting included constant US
|
||||
|
||||
Although the API is designed for use in POST requests, it can be used for GET requests in a limited mode.
|
||||
|
||||
|
||||
Warning: the Tera blockchain has a high rate of block confirmation (starting from 4 seconds), but since it uses PoW, it is possible to get into local orphan chains. Therefore, for a reliable transfer of value, we recommend that exchanges wait for additional time, such as 100 seconds, to interpret the finality of the transaction.
|
||||
|
||||
|
||||
Call format:
|
||||
```js
|
||||
{{Server}}/api/v2/{{MethodName}}
|
||||
@ -231,6 +235,7 @@ return:
|
||||
#### Parameters:
|
||||
* AccountID - account (account) number)
|
||||
* Count - maximum number of rows returned - history depth (default 100)
|
||||
* Confirm - min confirm for return tx (default 8)
|
||||
|
||||
option to set parameters for organizing page navigation:
|
||||
* NextPos - history line ID number (this value is taken from the last line of the previous result)
|
||||
|
@ -2,6 +2,32 @@
|
||||
|
||||
Данный API доступен если на ноде запущен публичный http-доступ. Т.е. задана константа HTTP_HOSTING_PORT
|
||||
|
||||
DappStaticCall - статический вызов метода смарт-контракта
|
||||
Example (GET)
|
||||
```js
|
||||
http://dappsgate.com:88/api/v1/DappStaticCall?MethodName=Test&Account=540
|
||||
```
|
||||
|
||||
Example (POST)
|
||||
```js
|
||||
http://dappsgate.com:88/api/v1/DappStaticCall
|
||||
{
|
||||
"MethodName": "Test",
|
||||
"Account":540
|
||||
|
||||
}```
|
||||
|
||||
return value:
|
||||
```js
|
||||
{"result":1,"RetValue":"Test-ok"}
|
||||
```
|
||||
|
||||
|
||||
see smart code of this example:
|
||||
http://dappsgate.com:88/smart/200
|
||||
|
||||
|
||||
|
||||
|
||||
#### Получение текущего статуса блокчейна
|
||||
http://194.1.237.94/GetCurrentInfo?Diagram=0
|
||||
|
@ -1,5 +1,5 @@
|
||||
# API v2 (для бирж и обменников)
|
||||
Работает с версии обновления 0.901
|
||||
Работает с версии обновления 0.991
|
||||
|
||||
|
||||
API предназначено для облегчения написания сторонних приложений. На стороне сервера выполняется криптография и операции POW. Поэтому оно не рекомендуется для публичного доступа, т.к. нет защиты от DDOS атак. Используйте его, если приложения такие как сервер биржи находятся в одной приватной сети.
|
||||
@ -12,6 +12,10 @@ API предназначено для облегчения написания с
|
||||
|
||||
Несмотря на то что API разработано для использования в POST запросах, в ограниченном режиме его можно использовать для GET запросов.
|
||||
|
||||
|
||||
Предупреждение: блокчейн Тера имеет высокую скорость подтверждения блока (начиная от 4 сек), но т.к. он использует PoW, то возможно попадание в локальные орфан цепочки. Поэтому для надежной передачи ценности мы рекомендуем биржам выжидать дополнительное время, например 100 секунд, для интерпретации финальности транзакции.
|
||||
|
||||
|
||||
Формат вызова
|
||||
```js
|
||||
{{Server}}/api/v2/{{MethodName}}
|
||||
@ -239,6 +243,7 @@ return:
|
||||
#### Параметры:
|
||||
* AccountID - номер счета (аккаунта)
|
||||
* Count - максимальное число возвращаемых строк - глубина истории (по умолчанию 100)
|
||||
* Confirm - min число подтверждений требуемых, чтобы транзакция попала в результат выдачи (по умолчанию 8)
|
||||
|
||||
вариант задания параметров для организации постраничной навигации:
|
||||
* NextPos - номер ид строки истории (это значение берется из последней строки предыдущего результата)
|
||||
|
@ -20,7 +20,6 @@ body
|
||||
|
||||
body.styleBrown
|
||||
{
|
||||
--colorText:#FFF;
|
||||
--color0:#503F13;
|
||||
--color1:#86754A;
|
||||
--color2:#F5E5BB;
|
||||
|
@ -940,16 +940,21 @@ function RetChangeSmart(Item)
|
||||
return '<DIV style="width: 204px;">' + Name + '<button onclick="ChangeSmart(' + Item.Num + ',' + Item.Value.Smart + ')" class="setsmart" style="height: ' + Height + 'px;min-height: ' + Height + 'px;">Set</button>' + State + '</DIV>';
|
||||
};
|
||||
|
||||
function RetHistoryAccount(Item)
|
||||
function RetHistoryAccount(Item,Name)
|
||||
{
|
||||
if(Item.Num < 16)
|
||||
return "" + Item.Num;
|
||||
return "<a class='olink' target='_blank' href='./history.html#" + Item.Num + "'>" + Item.Num + "</a>";
|
||||
var Num;
|
||||
if(Name)
|
||||
Num = Item[Name];
|
||||
else
|
||||
Num = Item.Num;
|
||||
if(Num < 16)
|
||||
return "" + Num;
|
||||
return "<a class='olink' target='_blank' href='./history.html#" + Num + "'>" + Num + "</a>";
|
||||
};
|
||||
|
||||
function RetBaseAccount(Item)
|
||||
{
|
||||
var Str = "" + Item.Account;
|
||||
var Str = RetHistoryAccount(Item, "Account");
|
||||
if(Item.AccountLength > 1)
|
||||
Str += "-" + (Item.Account + Item.AccountLength - 1);
|
||||
return Str;
|
||||
@ -972,7 +977,7 @@ function formatDate(now)
|
||||
"0") + ":" + String(minute).padStart(2, "0") + ":" + String(second).padStart(2, "0");
|
||||
};
|
||||
|
||||
function DateFromBlock(BlockNum,bAddEnter)
|
||||
function DateFromBlock(BlockNum)
|
||||
{
|
||||
var Str;
|
||||
if(window.FIRST_TIME_BLOCK)
|
||||
|
@ -12,6 +12,14 @@ var DiagramMap = {};
|
||||
var DiagramMapId = {};
|
||||
var LMouseOn = false;
|
||||
|
||||
function Rigth(Str,Count)
|
||||
{
|
||||
if(Str.length < Count)
|
||||
return Str;
|
||||
else
|
||||
return Str.substr(Str.length - Count);
|
||||
};
|
||||
|
||||
function SetHTMLDiagramItem(Item,width)
|
||||
{
|
||||
Item.mouseX = width - 50;
|
||||
@ -87,11 +95,15 @@ function DrawDiagram(Item)
|
||||
var arr = Item.arr;
|
||||
if(!arr)
|
||||
arr = Item.ArrList;
|
||||
var arrX = Item.arrX;
|
||||
var GreenValue = Item.value;
|
||||
var StepTime = Item.steptime;
|
||||
var StartNumber = Item.startnumber;
|
||||
var StartServer = Item.starttime;
|
||||
var mouseX = Item.mouseX;
|
||||
var KPrecision = Item.KPrecision;
|
||||
if(!KPrecision)
|
||||
KPrecision = 1;
|
||||
if(!arr)
|
||||
return ;
|
||||
var obj = document.getElementById(Item.id);
|
||||
@ -166,6 +178,7 @@ function DrawDiagram(Item)
|
||||
|
||||
function DrawLines(arr,mode,color)
|
||||
{
|
||||
var WasMove0 = 0;
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(Left, obj.height - Button);
|
||||
ctx.strokeStyle = color;
|
||||
@ -197,9 +210,17 @@ function DrawLines(arr,mode,color)
|
||||
VX1 -= 2;
|
||||
var x = StartX + ctx.lineWidth / 2 + (i) * KX;
|
||||
if(bLine)
|
||||
{
|
||||
if(!WasMove0)
|
||||
{
|
||||
WasMove0 = 1;
|
||||
ctx.moveTo(x, StartY - VX2);
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.lineTo(x, StartY - VX2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ctx.moveTo(x, StartY - VX1);
|
||||
@ -255,8 +276,8 @@ function DrawLines(arr,mode,color)
|
||||
if(mouseValue !== undefined)
|
||||
{
|
||||
ctx.fillStyle = mouseColor;
|
||||
var Str = "" + Math.floor(mouseValue + 0.5);
|
||||
ctx.fillText(Str, mouseX - 3, Top - 2);
|
||||
var Val = Math.floor(KPrecision * mouseValue + 0.5) / KPrecision;
|
||||
ctx.fillText("" + Val, mouseX - 3, Top - 2);
|
||||
}
|
||||
}
|
||||
ctx.fillStyle = "#000";
|
||||
@ -285,6 +306,10 @@ function DrawLines(arr,mode,color)
|
||||
var KDelitel = 1;
|
||||
var Step = arr.length / CountNameX;
|
||||
var StartTime, bNumber;
|
||||
if(arrX)
|
||||
{
|
||||
}
|
||||
else
|
||||
if(StartNumber !== undefined)
|
||||
{
|
||||
bNumber = 1;
|
||||
@ -321,6 +346,14 @@ function DrawLines(arr,mode,color)
|
||||
else
|
||||
Val = i * Step * StepTime;
|
||||
var Str;
|
||||
if(arrX)
|
||||
{
|
||||
Val = Math.floor(Val);
|
||||
Str = arrX[Val];
|
||||
if(Str === undefined)
|
||||
Str = "";
|
||||
}
|
||||
else
|
||||
if(bNumber)
|
||||
{
|
||||
Val = Math.floor((StartTime + Val) / KDelitel) * KDelitel;
|
||||
|
@ -304,8 +304,10 @@ function SendMoneyBefore()
|
||||
var StrTo = " to " + GetAccountText(Item, ToID);
|
||||
$("idWhiteOnSend").checked = 0;
|
||||
$("idOnSendText").innerHTML = "<B style='color:#ff4534'>" + SumSend + "</B> " + $("idCoinName").innerText + StrTo;
|
||||
if(SumSend >= 100000)
|
||||
if($("idSumSend").value >= 100000)
|
||||
{
|
||||
$("idOnSendText").innerHTML += "<BR><DIV style='color: yellow;'>WARNING: You are about to send a very large amount!</DIV>";
|
||||
}
|
||||
SetVisibleBlock("idBlockOnSend", 1);
|
||||
SetImg(this, 'idBlockOnSend');
|
||||
}
|
||||
@ -594,6 +596,19 @@ function OpenAttach()
|
||||
alert("DATA:\n" + JSON.stringify(Data2, "", 4));
|
||||
}
|
||||
};
|
||||
var CURRENCY, PUBKEY, NAME, SMART;
|
||||
|
||||
function SendTrCreateAccWait(Currency,PubKey,Name,Smart)
|
||||
{
|
||||
CURRENCY = Currency;
|
||||
PUBKEY = PubKey;
|
||||
NAME = Name;
|
||||
SMART = Smart;
|
||||
setTimeout(function ()
|
||||
{
|
||||
SendTrCreateAcc(CURRENCY, PUBKEY, NAME, 0, SMART, 0, 0);
|
||||
}, 50);
|
||||
};
|
||||
|
||||
function SendTrCreateAcc(Currency,PubKey,Description,Adviser,Smart,bFindAcc,bAddToPay)
|
||||
{
|
||||
@ -625,6 +640,29 @@ function ChangeSmart(NumAccount,WasSmart)
|
||||
if(Result !== null && Result != WasSmart)
|
||||
{
|
||||
var Smart = parseInt(Result);
|
||||
if(Smart)
|
||||
{
|
||||
GetData("GetDappList", {StartNum:Smart, CountNum:1}, function (Data)
|
||||
{
|
||||
if(Data && Data.result && Data.arr.length === 1)
|
||||
{
|
||||
SetSmartToAccount(NumAccount, Smart);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetError("Error smart number");
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
SetSmartToAccount(NumAccount, Smart);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function SetSmartToAccount(NumAccount,Smart)
|
||||
{
|
||||
var OperationID = 0;
|
||||
var Item = MapAccounts[NumAccount];
|
||||
if(Item)
|
||||
@ -641,7 +679,6 @@ function ChangeSmart(NumAccount,WasSmart)
|
||||
WriteUint(Body, TR.FromNum);
|
||||
WriteUint(Body, TR.OperationID);
|
||||
SendTrArrayWithSign(Body, TR.Account, TR);
|
||||
}
|
||||
};
|
||||
|
||||
function CheckLengthAccDesription(name,Length)
|
||||
|
@ -226,7 +226,7 @@ function FindLider()
|
||||
var Item = Arr[i];
|
||||
if(Item.SumPower === MaxKey)
|
||||
{
|
||||
SetStatus("Find " + Item.ip + ":" + Item.port + " with pow=" + Item.SumPower + " " + Max + " ping=" + Item.DeltaTime);
|
||||
SetStatus("Find " + Item.ip + ":" + Item.port + " with pow=" + Item.SumPower + "/" + MaxKey + " ping=" + Item.DeltaTime);
|
||||
MainServer = Item;
|
||||
SaveServerMap();
|
||||
break;
|
||||
|
@ -528,7 +528,6 @@
|
||||
{
|
||||
var bDisabled=(CurProjectValue!=$("idProjectList").value);
|
||||
|
||||
|
||||
var Arr=["idName","idShortName","idISIN","idCode","idHTML","idDescription","idTokenGenerate","idStartValue","idOwnerPubKey","idAccountLength","idStateFormat","idCategory1","idCategory2","idCategory3","idIcon","idBtIcon","idBtSendSmart"];
|
||||
for(var i=0;i<Arr.length;i++)
|
||||
{
|
||||
@ -539,6 +538,9 @@
|
||||
else
|
||||
item.classList.remove("Disabled");
|
||||
}
|
||||
|
||||
SetVisibleBlock("idRefHTML",bDisabled);
|
||||
|
||||
return !bDisabled;
|
||||
|
||||
}
|
||||
@ -567,6 +569,14 @@
|
||||
{
|
||||
var Smart=SetData.arr[0];
|
||||
LoadSmart("/file/"+Smart.BlockNum+"/"+Smart.TrNum);
|
||||
var Str="";
|
||||
|
||||
if(Smart.BaseState && Smart.BaseState.HTMLBlock)
|
||||
{
|
||||
var Url="/file/"+Smart.BaseState.HTMLBlock+"/"+Smart.BaseState.HTMLTr;
|
||||
Str="<a target='_blank' href='"+Url+"'>"+Url+"</a>";
|
||||
}
|
||||
$("idRefHTML").innerHTML=Str;
|
||||
//SetSmartToDialog(Smart,1);
|
||||
}
|
||||
else
|
||||
@ -610,11 +620,11 @@
|
||||
function SetCurrentSmart()
|
||||
{
|
||||
CurProjectValue=undefined;
|
||||
SetDialogEnabled();
|
||||
|
||||
var SmartValue=$("idSmartList").value;
|
||||
if(SmartValue)
|
||||
LoadSmart(SmartValue);
|
||||
SetDialogEnabled();
|
||||
}
|
||||
function FillSmart()
|
||||
{
|
||||
@ -840,7 +850,7 @@
|
||||
|
||||
|
||||
</DIV>
|
||||
UI (HTML):
|
||||
<DIV style="float: left;">UI (HTML):</DIV><DIV id="idRefHTML" style="float: left;">----</DIV>
|
||||
<textarea rows="15" cols="98" id="idHTML" style="width: 99%;">
|
||||
</textarea>
|
||||
</DIV>
|
||||
|
@ -157,6 +157,8 @@
|
||||
Data.WalletIsOpen=IsPrivateMode(localStorage["idPrivKey"]);
|
||||
Data.WalletCanSign=Data.WalletIsOpen;
|
||||
}
|
||||
CONFIG_DATA.WalletCanSign=Data.WalletCanSign;
|
||||
CONFIG_DATA.PubKey=Data.PubKey;
|
||||
}
|
||||
|
||||
SendMessage(Data);
|
||||
@ -397,31 +399,31 @@
|
||||
}
|
||||
|
||||
|
||||
var WasCheckInstall=0;
|
||||
var idInstallApp=0;
|
||||
function CheckInstall()
|
||||
{
|
||||
if(WasCheckInstall)
|
||||
return;
|
||||
setInterval(function ()
|
||||
if(!idInstallApp)
|
||||
idInstallApp=setInterval(RunCheckInstall,2000);
|
||||
}
|
||||
function RunCheckInstall()
|
||||
{
|
||||
if(CONFIG_DATA && CONFIG_DATA.ArrWallet && CONFIG_DATA.ArrWallet.length===0)
|
||||
{
|
||||
WasCheckInstall=1;
|
||||
var StrRef;
|
||||
if(MainServer)
|
||||
StrRef='<A href="./web-wallet.html#TabAccounts">ACCOUNTS</A>';
|
||||
StrRef='<A class="btcreate" href="./web-wallet.html#TabAccounts">Accounts</A>';
|
||||
else
|
||||
{
|
||||
if(localStorage["BIGWALLET"])
|
||||
StrRef='<A href="/wallet.html#TabAccounts">CONFIG</A>'
|
||||
StrRef='<A class="btcreate" href="/wallet.html#TabAccounts">Config</A>'
|
||||
else
|
||||
StrRef='<A href="/web-wallet.html#TabAccounts">ACCOUNTS</A>';
|
||||
StrRef='<A class="btcreate" href="/web-wallet.html#TabAccounts">Accounts</A>';
|
||||
}
|
||||
|
||||
SetStatus('<DIV style="background-color: peachpuff;">For install this application goto '+StrRef+' tab, select your account, press "Set" and enter smart number: <B>'+SMART.Num+'</B><DIV>');
|
||||
var Str='<DIV style="background-color: #c8ecff;">For install this app press: <button class="btcreate" onclick="InstallApp()">Create account</button> or goto '+StrRef+' tab and Set smart number <B>'+SMART.Num+'</B> to your account<DIV>';
|
||||
SetStatus(Str);
|
||||
}
|
||||
|
||||
},2000);
|
||||
}
|
||||
|
||||
//LIB
|
||||
@ -472,8 +474,45 @@
|
||||
SetStatus("<DIV style='color:red'><B>"+Str+"</B></DIV>");
|
||||
}
|
||||
|
||||
|
||||
function CreateNewWebKeys()
|
||||
{
|
||||
var arr = new Uint8Array(32);
|
||||
window.crypto.getRandomValues(arr);
|
||||
var PrivKey=GetHexFromArr(sha3(arr));
|
||||
localStorage["idPrivKey"]=PrivKey;
|
||||
localStorage["idPubKey"]=GetHexFromArr(SignLib.publicKeyCreate(PrivKey,1));
|
||||
CONFIG_DATA.PubKey=localStorage["idPubKey"];
|
||||
|
||||
console.log("CreateNewWebKeys: "+CONFIG_DATA.PubKey);
|
||||
}
|
||||
|
||||
|
||||
function InstallApp()
|
||||
{
|
||||
if(!CONFIG_DATA.WalletCanSign)
|
||||
{
|
||||
if(localStorage["BIGWALLET"])
|
||||
{
|
||||
SetError("Pls, open wallet");
|
||||
return;
|
||||
}
|
||||
CreateNewWebKeys();
|
||||
}
|
||||
SetStatus("Calculate Tx, wait pls ...");
|
||||
//SendTrCreateAccWait(0,SMART.Name,SMART.Num);
|
||||
|
||||
//console.log("PubKey: "+CONFIG_DATA.PubKey);
|
||||
|
||||
var TR=GetTrCreateAcc(0,CONFIG_DATA.PubKey,SMART.Name,0,SMART.Num);
|
||||
var Body=GetBodyCreateAcc(TR);
|
||||
SendTransaction(Body,TR);
|
||||
|
||||
if(idInstallApp)
|
||||
{
|
||||
clearInterval(idInstallApp);
|
||||
idInstallApp=setInterval(RunCheckInstall,30000);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -499,6 +538,17 @@
|
||||
margin: 0;
|
||||
background-color:white;
|
||||
}
|
||||
.btcreate
|
||||
{
|
||||
height:20px;
|
||||
background-color: #347867;
|
||||
color: white;
|
||||
cursor: pointer;
|
||||
border-radius: 3px;
|
||||
padding: 2px;
|
||||
text-decoration: none;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
@ -154,7 +154,7 @@
|
||||
{
|
||||
var Str;
|
||||
if(Item.Direct===Direct)
|
||||
Str=RetHistoryAccount({Num:Item.CorrID});
|
||||
Str=RetHistoryAccount(Item,"CorrID");
|
||||
else
|
||||
Str=AccountID;
|
||||
|
||||
|
@ -1549,12 +1549,16 @@
|
||||
<th id="Item.Description" class="code">Description</th>
|
||||
<th id="(RetCategory(Item))" class="">Category</th>
|
||||
|
||||
<th id="RetBaseAccount(Item)" class="num">Base Account</th>
|
||||
<th id="Item.Owner" class="num">Owner</th>
|
||||
<th id="(RetBaseAccount(Item))" class="num">Base Account</th>
|
||||
|
||||
<th id="(RetHistoryAccount(Item,'Owner'))" class="num">Owner</th>
|
||||
|
||||
<th id="RetBool(Item.TokenGenerate)" class="bool">Token generate</th>
|
||||
<!--<th id="Item.ISIN" class="num">ISIN</th>-->
|
||||
<th id="(RetOpenBlock(Item.BlockNum,1))" class="num">Block Num</th>
|
||||
|
||||
<!--<th id="GetHexFromArr(Item.SumHash)" class="hash">SumHash</th>-->
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
@ -1721,8 +1725,11 @@
|
||||
<th id="Item.Num" class="num">Num</th>
|
||||
<th id="(RetOpenBlock(Item.BlockNum,Item.TrDataLen))" class="num">Block</th>
|
||||
<th id="(escapeHtml(DateFromBlock(Item.BlockNum,1)))" class="date">Date</th>
|
||||
<th id="GetHexFromArr(Item.Hash)" class="code">Hash</th>
|
||||
<th id="GetHexFromArr(Item.AccHash)" class="code">AccHash</th>
|
||||
<th id="GetHexFromArr(Item.SumHash)" class="code">SumHash</th>
|
||||
<th id="Item.AccountMax" class="num">AccountMax</th>
|
||||
<th id="Item.SmartCount" class="num">SmartCount</th>
|
||||
<th id="GetHexFromArr(Item.SmartHash)" class="code">SmartHash</th>
|
||||
</tr>
|
||||
</table>
|
||||
<INPUT type="button" onclick="ViewPrev(DefHash)" class="btdoit bt" value="<< Prev">
|
||||
@ -1809,8 +1816,7 @@
|
||||
|
||||
<DIV id="idBlockOnSend" style="display: none">
|
||||
<DIV align="center">
|
||||
Send <B id="idOnSendText"></B>
|
||||
|
||||
Send <B id="idOnSendText"></B><BR>
|
||||
<button onclick="SendMoney2()" id="idBtOnSend" class="radius">Send</button>
|
||||
<button onclick='SetVisibleBlock("idBlockOnSend",0);' class="radius">Cancel</button>
|
||||
|
||||
|
1102
Source/HTML/web-wallet-cn.html
Normal file
1102
Source/HTML/web-wallet-cn.html
Normal file
File diff suppressed because it is too large
Load Diff
@ -231,9 +231,9 @@
|
||||
}
|
||||
|
||||
|
||||
function SetVisibleItemsKeys(EditFlag)
|
||||
function SetVisibleItemsKeys(EditFlag,bOpenEdit)
|
||||
{
|
||||
if(EditFlag)
|
||||
if(bOpenEdit)
|
||||
{
|
||||
$("idPrivKeyEdit").value=$("idPrivKey").value;
|
||||
}
|
||||
@ -344,7 +344,7 @@
|
||||
return;
|
||||
}
|
||||
SetStatus("Calculate Tx, wait pls ...");
|
||||
SendTrCreateAccWait(Currency,Name,Smart);
|
||||
SendTrCreateAccWait(Currency,$("idPubKey").value,Name,Smart);
|
||||
}
|
||||
SetVisibleBlock("idAccountEdit",0)
|
||||
}
|
||||
@ -353,17 +353,6 @@
|
||||
SetVisibleBlock("idAccountEdit",0)
|
||||
}
|
||||
|
||||
var CURRENCY,NAME,SMART;
|
||||
function SendTrCreateAccWait(Currency,Name,Smart)
|
||||
{
|
||||
CURRENCY=Currency;
|
||||
NAME=Name;
|
||||
SMART=Smart;
|
||||
setTimeout(function ()
|
||||
{
|
||||
SendTrCreateAcc(CURRENCY,$("idPubKey").value,NAME,0,SMART,0,0);
|
||||
},50)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -836,7 +825,7 @@
|
||||
<tr id="WalRow1">
|
||||
<td>Wallet:</td>
|
||||
<td><button id="idPrivKeyButton" onclick="OpenWallet()">Wallet opened: </button></td>
|
||||
<td><button onclick="SetVisibleItemsKeys(1)" class="btkey bigs">Edit...</button></td>
|
||||
<td><button onclick="SetVisibleItemsKeys(1,1)" class="btkey bigs">Edit...</button></td>
|
||||
</tr>
|
||||
<tr id="WalRow2" style="display: none">
|
||||
<td>Private key:</td>
|
||||
@ -988,7 +977,7 @@
|
||||
<th id="Item.Description" class="code dappdesc">Description</th>
|
||||
<th id="(RetCategory(Item))" class="">Category</th>
|
||||
|
||||
<th id="RetBaseAccount(Item)" class="num">Base Account</th>
|
||||
<th id="(RetBaseAccount(Item))" class="num">Base Account</th>
|
||||
<th id="Item.Owner" class="num">Owner</th>
|
||||
<th id="RetBool(Item.TokenGenerate)" class="bool">Token generate</th>
|
||||
<!--<th id="Item.ISIN" class="num">ISIN</th>-->
|
||||
|
@ -1,5 +1,7 @@
|
||||
# TERA BLOG
|
||||
|
||||
If you have written something important about TERA on a worldwide important portal and you think that you deserve a reward, please contact us:
|
||||
* Discord: https://discord.gg/CvwrbeG.
|
||||
* Telegram: @PsyArcus.
|
||||
If you have written something important about TERA and think you deserve a reward, please contact US:
|
||||
* Discord: https://discord.gg/CvwrbeG
|
||||
* Telegram: [@PsyArcus](https://web.telegram.org/#/im?p=@PsyArcus)
|
||||
* See more about reward: [TERA CONTENT FUND](https://terafoundation.org/tera-content-fund.html)
|
||||
|
||||
|
135
Source/SITE/CONTENT/en-changelog-text.md
Normal file
135
Source/SITE/CONTENT/en-changelog-text.md
Normal file
@ -0,0 +1,135 @@
|
||||
v. 0.897
|
||||
|
||||
The API-2 is designed to make it easier to write third-party applications. Server-side cryptography and POW operations are performed. Therefore, it is not recommended for public access, because it is not protected from DDOS attacks. Use it if applications such as the exchange server are on the same private network.
|
||||
|
||||
v. 0.884
|
||||
Will be enhanced the behavior of the constants COREY_WATCH_DOG. If you will be the number 2: "COREY_WATCH_DOG": 2, instead of an overload will just trim the blocks on the 5000, it will save time filling out the memory hashes. I. e. mining will practically go without interruption
|
||||
|
||||
v. 0.880
|
||||
It contains API Protocol improvements for DApp.
|
||||
|
||||
v. 0.867
|
||||
Made Protocol support light-wallet, fixed a bug in validate download chains.
|
||||
The update is optional and can be skipped.
|
||||
|
||||
v. 0.811
|
||||
If you set a constant:
|
||||
|
||||
"WATCHDOG_BADACCOUNT": 1
|
||||
|
||||
then "BAD ACCOUNT Has"error checking will be enabled. When accumulating them in the amount of 60, automatic cutting of the blockchain into 5000 blocks will be launched, which in theory leads to the removal of this error. But this is not accurate.
|
||||
|
||||
v. 0.783
|
||||
Fix history and dapp event bugs.
|
||||
|
||||
v. 0.753
|
||||
The update is partially completed:
|
||||
1. Half of the nodes have completed the update
|
||||
2. The second half performs the transaction overwrite procedure (it will take a long time). To speed up, you can download the DB folder from the torrent.
|
||||
|
||||
v. 0.727
|
||||
Fix minor bugs.
|
||||
|
||||
v. 0.719
|
||||
The update is desirable for the stability of the network, which consists of nodes from different regions of the world. The algorithm of correction of the current number of the current block-robust with respect to the time deviation.
|
||||
|
||||
v. 0.718
|
||||
The consensus algorithm was returned to its original level (0.703). The experiments of the new consensus failed. I'll think.
|
||||
Thanks for your patience
|
||||
|
||||
v. 0.703
|
||||
Fix visual part of DApp.
|
||||
Made less memory usage when you turn off the logging of statistics.
|
||||
The update does not contain any changes in the blockchain communication Protocol and can be omitted.
|
||||
|
||||
v. 0.685
|
||||
Update 685 contains two mining constants (on the CONFIG tab, the CONSTANTS button):
|
||||
|
||||
"COUNT_MINING_CPU": 0,
|
||||
"SIZE_MINING_MEMORY": 0,
|
||||
|
||||
If set to COUNT_MINING_CPU that starts the specified number of processes of mining, you can set more or fewer than there are physical cores.
|
||||
|
||||
If the value SIZE_MINING_MEMORY is set, this value is distributed to all processes (the specified number is divided by the number of processes).
|
||||
|
||||
v. 0.672
|
||||
Fixed a hash table calculation bug (OUR ACCOUNT).
|
||||
From the number 10195000 the calculation of the block hash changes.
|
||||
|
||||
v. 0.671
|
||||
The current update 0.671 contains an improved miner. The exchange Protocol has not changed. It is recommended only if you want to improve mining.
|
||||
|
||||
v. 0.666
|
||||
Button added Auto-update to wallet (near button mining). If the update mode is turned off, but a new version is uploaded to the network, the button becomes orange and it is written in the title bar of the window via slash (Example: 0.661/663).
|
||||
Added the ability to send money to any public address. In this case, a new account is created upon receipt. The first line of the payment purpose is used as the name. For the creation of the account will be charged a fee.
|
||||
Added the possibility of unlimited creation of new accounts, but with a fee. Now the fee is 10 Tera, but as the rate of the Tera increases, it will decrease. The fee is paid to account 0. To do this, when creating a new account, use the "Add to Pay list"button. Clicking on it on the Send tab creates a payment transaction for 10 Tera with the order to create an account. It must be sent manually-by pressing the Send button.
|
||||
Added smart contracts. More detail will be description will be here soon.
|
||||
|
||||
v. 0.555
|
||||
Fix problem with pow process.
|
||||
More hashrate.
|
||||
|
||||
v. 0.553
|
||||
Fixed small bug with update version installation (previously installed always, even if auto-update is disabled).
|
||||
With block number 7000000 introduced protection against DDOS attacks when creating new accounts. New accounts will be allowed to be created only in limited quantities. For an unlimited number in the future will be expanded standard transaction transfer of funds. We plan to add support for transferring money to the wallet address (public key) without specifying an account. In this case, a new account will be created automatically and a small fee will be charged for its creation (for DDOS protection). Ordinary transaction of transfer of funds stating the account will not require a fee.
|
||||
|
||||
v. 0.545
|
||||
Full utilization of memory and CPU.
|
||||
|
||||
More hashrate.
|
||||
|
||||
v. 0.542
|
||||
More memory optimization. More hashrate.
|
||||
|
||||
v. 0.501
|
||||
Small bugs fix.
|
||||
|
||||
v. 0.517
|
||||
A small change in security. For limited web access to the wallet, you can set the external ip address of the computer from which access is allowed in the constant "HTTP_IP_CONNECT".
|
||||
Example:
|
||||
"HTTP_IP_CONNECT": "111.222.220.230",
|
||||
Note:
|
||||
Access to the wallet via the local address 127.0.0.1 is always allowed.
|
||||
|
||||
v. 0.501
|
||||
Small bugs fix.
|
||||
|
||||
v. 0.452
|
||||
The power of the network is growing. Now its value 2^27.6 = 200Mh/s.
|
||||
|
||||
v. 0.450
|
||||
Reduce traffic pushed.
|
||||
|
||||
v. 0.418
|
||||
Candidate stable 2 pushed.
|
||||
|
||||
v. 0.366
|
||||
Minor changes to the interface part update 366:
|
||||
|
||||
The utility section now has the following buttons:
|
||||
1. Rewrite transactions
|
||||
2. Truncate chain
|
||||
3. Clear DataBase
|
||||
|
||||
The first two items require you to enter a parameter - the depth of the chain for processing in blocks starting from the current one. The last point - clears completely the database, without affecting the parameters of the wallet and server constants. Works the same as deleting the DATA / DB folder.
|
||||
|
||||
v. 0.214
|
||||
For the network, it is very important that the time on all nodes is the same. Otherwise, the exchange of packets becomes impossible. With the help of special algorithms, it is synchronized automatically and the general direction is such that it is equal to the UTC time. If you are sure that your server has exact time synchronization, then you can disable automatic synchronization (but under your responsibility). This is done in constants, set the value: "AUTO_COORECT_TIME": 0
|
||||
|
||||
v. 0.171
|
||||
The second version with spam protection is released. Available in auto-update mode.
|
||||
|
||||
v. 0.169
|
||||
Ban list enable.
|
||||
|
||||
v. 0.169
|
||||
Ban list enable.
|
||||
|
||||
v. 0.162
|
||||
If you do not specify a password for the http remote access port, access is allowed only from the local address 127.0.0.1.
|
||||
|
||||
v. 0.156
|
||||
Added automatic tracking of the processes involved in mining. If processes lose connection with the main process, they are destroyed.
|
||||
|
||||
v. 0.155
|
||||
You can set http password during the program installation from command line, example: node set httpport:8080 password:123.
|
1
Source/SITE/CONTENT/en-changelog-title.md
Normal file
1
Source/SITE/CONTENT/en-changelog-title.md
Normal file
@ -0,0 +1 @@
|
||||
# TERA CHANGELOG
|
@ -1,3 +1,4 @@
|
||||
TERA is a platform for developing applications in a decentralized network. Programs can manage and transfer any digital values, including coins and tokens. This platform allows you to build a world economy without borders. The network is built on a highly reliable blockchain Protocol with PoW consensus.
|
||||
It is our great pleasure to invite you to join us to mine TERA, a coin that offers solutions for issues of existing cryptocurrencies, namely centralization, transaction throughput, transaction speed, confirmation times, transaction fees and general usability and difficulty of integration into existing payment and financial systems.
|
||||
|
||||
We have managed to create a blockchain with 1 second block time, 8 seconds for full confirmation of transfer and zero fees. On top of that TERA blockchain is capable of throughput of 1000 transactions per second while retaining all praised blockchain features and bringing huge possibilities for further development and seamless integration with existing infrastructure as well as with new emerging technologies.
|
||||
|
@ -1 +1 @@
|
||||
# ABOUT TERA BLOCKCHAIN
|
||||
# ABOUT TERA PLATFORM
|
19
Source/SITE/CONTENT/en-index-changelog.md
Normal file
19
Source/SITE/CONTENT/en-index-changelog.md
Normal file
@ -0,0 +1,19 @@
|
||||
## UPDATES
|
||||
* **v. 0.897:**
|
||||
The API-2 is designed to make it easier to write third-party applications. Server-side cryptography and POW operations are performed. Therefore, it is not recommended for public access, because it is not protected from DDOS attacks. Use it if applications such as the exchange server are on the same private network.
|
||||
|
||||
* **v. 0.884:**
|
||||
Will be enhanced the behavior of the constants COREY_WATCH_DOG. If you will be the number 2: "COREY_WATCH_DOG": 2, instead of an overload will just trim the blocks on the 5000, it will save time filling out the memory hashes. I. e. mining will practically go without interruption
|
||||
|
||||
* **v. 0.880:**
|
||||
It contains API Protocol improvements for DApp.
|
||||
|
||||
* **v. 0.877:**
|
||||
Today will be an update. The update improves work of DApp.
|
||||
The update is optional — you can skip it.
|
||||
|
||||
* **v. 0.867:**
|
||||
Made Protocol support light-wallet, fixed a bug in validate download chains.
|
||||
The update is optional and can be skipped.
|
||||
|
||||
[Full Changelog...](/changelog.html)
|
@ -1,3 +1,4 @@
|
||||
## UPDATES
|
||||
* **v. 0.897:**
|
||||
The API-2 is designed to make it easier to write third-party applications. Server-side cryptography and POW operations are performed. Therefore, it is not recommended for public access, because it is not protected from DDOS attacks. Use it if applications such as the exchange server are on the same private network.
|
||||
|
||||
@ -14,3 +15,5 @@ The update is optional — you can skip it.
|
||||
* **v. 0.867:**
|
||||
Made Protocol support light-wallet, fixed a bug in validate download chains.
|
||||
The update is optional and can be skipped.
|
||||
|
||||
[Full Changelog...](/changelog.html)
|
16
Source/SITE/CONTENT/en-index-lastnews.md
Normal file
16
Source/SITE/CONTENT/en-index-lastnews.md
Normal file
@ -0,0 +1,16 @@
|
||||
## NEWS
|
||||
|
||||
|
||||
**Local blockchain desynchronization detector test**
|
||||
|
||||
|
||||
|
||||
The test network begins the test of a new detector for determining the desynchronization of the blockchain from the main chain.
|
||||
If the last 10 blocks are created by their own node, then their POW should not differ more than 10 times from the previous blocks, otherwise the forced synchronization of the blockchain with the network is started.
|
||||
Settings can be changed-new constant added:
|
||||
```
|
||||
"RESYNC_CONDITION": {
|
||||
"OWN_BLOCKS": 10,
|
||||
"K_POW": 10
|
||||
},
|
||||
```
|
7
Source/SITE/CONTENT/en-index-link-1.md
Normal file
7
Source/SITE/CONTENT/en-index-link-1.md
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
* [1. TERA Source Code](https://sourceforge.net/p/tera/code/ci/master/tree/)
|
||||
* [2. TERA DApp PAPER (ENG)](https://docs.google.com/document/d/1PXVBbMKdpsAKPkO9UNB5B-LMwIDjylWoHvAAzzrXjvU/edit?usp=sharing)
|
||||
* [3. TERA DApp PAPER (RUS)](https://docs.google.com/document/d/1SkD4yc_POaGRMJRC6yGkDfdJUuKbcyq3JpG0cBXeYGM/edit?usp=sharing/)
|
||||
* [4. FAQ](https://docs.google.com/document/d/10yXAKxaU7YgrQnbdXu_L7WWovUoRtdJwo3tXXaGZGSQ/edit?usp=sharing/)
|
||||
* [5. TERA API](https://sourceforge.net/p/tera/code/ci/master/tree/Doc/Eng/API.md)
|
||||
* [6. TERA API-2 (for Exchanges)](https://gitlab.com/terafoundation/tera/blob/master/Doc/Eng/API2.md)
|
7
Source/SITE/CONTENT/en-index-link-2.md
Normal file
7
Source/SITE/CONTENT/en-index-link-2.md
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
* [1. TERA on QBTC Exchange](https://www.qbtc.ink/trade?symbol=TERA_BTC)
|
||||
* [2. TERA on Bitalong Exchange](https://www.bitalong.com/trade/index/market/tera_usdt/)
|
||||
* [3. TERA on Bitmesh Exchange](https://bitmesh.com/exchange?market=btc_tera#/)
|
||||
* [4. TERA on CHAOEX Exchange](https://chaoex-en-us.udesk.cn/hc/articles/83487)
|
||||
* [5. TERA on CITEX Exchange](https://www.citex.co.kr/#/trade/2/37)
|
||||
* [6. TERA Roadmap](/#roadmap)
|
5
Source/SITE/CONTENT/en-index-link-3.md
Normal file
5
Source/SITE/CONTENT/en-index-link-3.md
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
* [1. TERA Mining Documentation](https://sourceforge.net/p/tera/code/ci/master/tree/README.md)
|
||||
* [2. TERA HASH](https://docs.google.com/document/d/18DtASGhrbRwXCAkQR1hQG0lVdrStp4CgA-pd6hicwfo/edit?usp=sharing/)
|
||||
|
||||
|
9
Source/SITE/CONTENT/en-index-link-4.md
Normal file
9
Source/SITE/CONTENT/en-index-link-4.md
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
* [1. TERA Website](https://terafoundation.org/)
|
||||
* [2. TERA EXPLORER](https://terafoundation.org/explorer.html)
|
||||
* [3. TERA WALLET](https://terafoundation.org/web-wallet.html)
|
||||
* [4. TERA NETWORK MAP](https://terafoundation.org/map.html)
|
||||
* [5. TERA WHITE PAPER (EN)](https://terafoundation.org/files/TERA_WP_EN.pdf)
|
||||
* [6. TERA WHITE PAPER (RU)](https://terafoundation.org/files/TERA_WP_RU.pdf)
|
||||
* [7. TERA WHITE PAPER (DE)](https://terafoundation.org/files/TERA_WP_DE.pdf)
|
||||
* [8. TERA WHITE PAPER (CN)](https://sourceforge.net/p/tera/code/ci/master/tree/Doc/Chinese/WP_chinese.pdf?format=raw)
|
9
Source/SITE/CONTENT/en-index-link-5.md
Normal file
9
Source/SITE/CONTENT/en-index-link-5.md
Normal file
@ -0,0 +1,9 @@
|
||||
|
||||
* [1. TERA ANN on BitcoinTalk](https://bitcointalk.org/index.php?topic=4573801.0)
|
||||
* [2. TERA on Twitter](https://twitter.com/terafoundation)
|
||||
* [3. TERA on Reddit](https://www.reddit.com/user/Terafoundation)
|
||||
* [4. TERA on Discord](https://discord.gg/CvwrbeG)
|
||||
* [5. TERA Telegram Chanel](https://web.telegram.org/#/im?p=@terafoundation)
|
||||
* [6. TERA on QQ](https://jq.qq.com/?_wv=1027&k=58VsQxc)
|
||||
|
||||
|
4
Source/SITE/CONTENT/en-index-link-6.md
Normal file
4
Source/SITE/CONTENT/en-index-link-6.md
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
* [FMessenger](http://freetimes.cc/fmessenger/)
|
||||
|
||||
|
@ -1,27 +1,37 @@
|
||||
1. SCOPE
|
||||
|
||||
These are the Terms of Use (hereinafter referred to as the “Terms”) of the TERA Foundation (hereinafter referred to as “TERA”, ”we” or “us”). These Terms apply to any access and use of TERA Hub, TERA Nano and TERA Commander (collectively referred to hereinafter as “TERA Wallets” or “TERA Wallet”), the TERA cryptographic token (hereinafter referred to as “TERA”), the TERA website at https://www.terafoundation.org/, the online services, and any TERA’s services related to or utilizing any of the foregoing which we refer to in these Terms, collectively, as “Services”, “TERA Services” or “our Services”.
|
||||
|
||||
|
||||
These are the Terms of Use (hereinafter referred to as the “Terms”) of the TERA Foundation (hereinafter referred to as “TERA”, ”we” or “us”). These Terms apply to any access and use of TERA DEX, TERA DApp and TERA Wallet, the TERA cryptographic coin (hereinafter referred to as “TERA”), the TERA website at https://www.terafoundation.org/, the online services, and any TERA’s services related to or utilizing any of the foregoing which we refer to in these Terms, collectively, as “Services”, “TERA Services” or “our Services”.
|
||||
|
||||
|
||||
2. ELIGIBILITY AND AGREEMENT
|
||||
|
||||
|
||||
You must ensure that you use and access TERA Services only in your own name. If you are acting for a legal entity, you must ensure that you:
|
||||
(a) use and access TERA Services on behalf of the legal entity; and
|
||||
(b) that you are authorised to enter into transactions on behalf of the legal entity.
|
||||
|
||||
|
||||
3. YOUR RESPONSIBILITIES REGARDING THE USE OF THE SERVICES
|
||||
|
||||
|
||||
You are also responsible for maintaining adequate security, control and confidentiality of your device access, your TERA Wallets information, including passwords, passphrases, private keys or other codes associated with your TERA Wallets and any activity occurring within these TERA Wallets. The loss or compromise of this information may result in unauthorized access of your TERA Wallets, and loss or theft of any TERA and other cryptographic tokens held in your TERA Wallets.
|
||||
If you believe your TERA Wallets have been compromised, or you need to report a security incident, or you have experienced any operational problems, or have a security concern, please contact us immediately at help@terafoundation.org describing the issue at hand as thoroughly as possible including the date, type of problem and part of the TERA site or TERA Services where you experienced that problem. You are responsible for (i) immediately notifying us of any unauthorized use of your password or TERA Wallets or any other breach of security, and (ii) ensuring that you log out from your TERA Wallets at the end of each session when accessing the TERA Services.
|
||||
We have no responsibility for any loss that you suffer as a result of failing to comply with this section or failure to follow or act on any notices or alerts that we may send to you.
|
||||
|
||||
|
||||
4. AVAILABILITY OF SERVICES
|
||||
|
||||
|
||||
Subject to these Terms, TERA shall use reasonable efforts to make available, operate and maintain the TERA Services during the term of these Terms and to permit you to access and use the TERA Services in accordance with these Terms. TERA shall use all reasonable efforts to promptly notify you of any difficulties experienced by us or other participants with respect to their access to or the use of the TERA Services, but only to the extent that TERA is aware of such difficulties and reasonably determines that they are material to your access and use of the TERA Services. Similarly, you shall notify TERA the soonest possible in case you become aware of any material technical failures of or difficulties with the TERA Services or upon becoming aware of any material breach (or any event which, by giving notice and/or the lapse of time, would constitute a material breach) of these Terms.
|
||||
Our Services may evolve over time. This means we may apply changes, replace, or discontinue (temporarily or permanently) our Services at any time for any reasonable cause with two days’ notice or without notice in case of a Force Majeure. In this case, you may be prevented from accessing or using our Services. If, in our sole discretion, we decide to permanently discontinue our Services, we will provide you with a notice via our website, via our Twitter account or any other means of communication we deem appropriate.
|
||||
You accept and acknowledge that the TERA Services may not be accessible in every country of your residence, in particular because of regulatory requirements.
|
||||
|
||||
|
||||
5. FORCE MAJEURE
|
||||
|
||||
|
||||
A Force Majeure Event includes without limitation each of the following:
|
||||
a) Government actions, the outbreak of war or hostilities, the threat of war, acts of terrorism, national emergency, riot, civil disturbance, sabotage, requisition, or any other international calamity, economic or political crisis;
|
||||
b) Act of God, earthquake, tsunami, hurricane, typhoon, accident, storm, flood, fire, epidemic or other natural disaster;
|
||||
@ -29,8 +39,10 @@ c) Labour disputes and lock-out;
|
||||
d) Breakdown, failure or malfunction of any electronic, network and communication lines or systems (not due to the fault of TERA);
|
||||
e) Any event, act or circumstances not reasonably within TERA’s control and the effect of that event(s) is such that TERA is not in a position to take any reasonable action to cure the default.
|
||||
|
||||
|
||||
6. RISKS
|
||||
|
||||
|
||||
You understand and accept the risks in connection with the use of the TERA Wallet app and using the Services as set forth above and hereinafter. In particular, but not limited to, you understand the inherent risks listed hereinafter:
|
||||
a) Risk of software weaknesses: You understand and accept that the underlying software application and software platform is still in an early development stage and unproven, why there is no warranty that the Services will be uninterrupted or error-free and why there is an inherent risk that the software could contain weaknesses, vulnerabilities or bugs causing, inter alia, the complete loss of TERA.
|
||||
b) Regulatory risk: You understand and accept that blockchain technology allows new forms of interaction and that it is possible that certain jurisdictions will apply existing regulations on, or introduce new regulations addressing, blockchain technology based applications, which may be contrary to the current setup of TERA and which may, inter alia, result in substantial modifications of the TERA Services, including its termination.
|
||||
@ -38,26 +50,34 @@ c) Risk of loss of private key or passphrase(s): TERA Wallet can only be accesse
|
||||
d) Risk of voting attacks: You understand and accept that the blockchain used for by TERA is susceptible to voting attacks, including but not limited to majority voting power attacks, “selfish-voting” attacks, and race condition attacks. Any successful attacks present a risk to the TERA Services.
|
||||
e) Risk of delegate attacks: You understand and accept that the blockchain used for by TERA is susceptible to delegate attacks, including but not limited to double-spending attacks, majority delegate attacks, and race condition attacks. Any successful attacks present a risk to the TERA Services.
|
||||
|
||||
|
||||
7. PUBLIC AND PRIVATE KEY, PASSPHRASES
|
||||
|
||||
|
||||
When you create a TERA Wallet, the Services generate a digital private and public key pair and a passphrase. The Services never store either private key or passphrase. The public key generated by the Services is being used to generate a TERA Wallet address, and may be shared with the network and with others to complete transactions. The private key is associated to a TERA Wallet address and must be used in conjunction with the TERA Wallet address to authorize transactions from or to that TERA address.
|
||||
You need to make sure that your passphrase(s) are properly backed up and protected from theft.
|
||||
|
||||
|
||||
8. DATA PROTECTION
|
||||
|
||||
|
||||
The information provided pursuant to these Terms will be used by TERA for the purposes of providing you with services and data pursuant to these Terms and enabling TERA to perform its activities.
|
||||
You acknowledge and agree that TERA may disclose your data, including personal data and sensitive personal data as defined under the Swiss Federal Data Protection Act (“Participant Data”) to outside organisations for the purpose of providing services and data to you, and performing its activities. You explicitly consent to the export of your data to a location outside your country of domicile and to third parties outside of TERA.
|
||||
|
||||
|
||||
9. PROHIBITED ACTIVITIES
|
||||
|
||||
|
||||
You agree that you will not use the TERA Services to perform any type or sort of illegal activity or to take any action that negatively affects the performances of the TERA Services. You may not engage via the Services in any of the following activities, nor help a third party in any such activity to:
|
||||
1) attempt to gain unauthorized access to our Services or another user’s TERA Wallet;
|
||||
2) make any attempt to bypass or circumvent any security features;
|
||||
3) violate any law, statute, ordinance, regulation or these Terms and other contractual documents as referred to herein;
|
||||
4) reproduce, duplicate, copy, sell or resell our Services for any purpose except as authorized in these Terms;
|
||||
|
||||
|
||||
10. DEFAULT
|
||||
|
||||
|
||||
Each of the following constitutes an “Event of Default”:
|
||||
a) Where any representation or warranty made by you is or becomes untrue;
|
||||
b) Any other circumstance where TERA reasonably believes that it is necessary or desirable to take any action set out in the below paragraph;
|
||||
@ -70,56 +90,3 @@ a) Terminate these Terms without notice;
|
||||
b) Close any or all of your TERA Wallets;
|
||||
c) Refuse to open a new TERA Wallet for you.
|
||||
|
||||
11. INDEMNIFICATION
|
||||
|
||||
You agree to indemnify, defend and hold TERA, its employees, agents, consultants, subsidiaries, partners, affiliates, and licensors, harmless against any and all claims, costs, losses, damages, liabilities, judgments and expenses (including reasonable fees of attorneys and other professionals) arising from or in any way related to your use of our Services, your violation of these Terms, or your violation of any rights of any other person or entity.
|
||||
|
||||
12. LIMITATION OF LIABILITY
|
||||
|
||||
To the extent permitted by applicable law, TERA and its auxiliary persons shall not be liable for any damage arising out of, or in connection with, this agreement.
|
||||
TERA shall assume no liability for any further claims, e.g. relating to compensation for indirect or consequential loss, lost profit or loss of earnings, unrealised savings or additional expense incurred, regardless of the legal grounds.
|
||||
You are fully aware that the access to and the use of the TERA Services through the internet, the TERA Wallets and from abroad might violate foreign laws applicable to you. You undertake to inform yourself and to assume sole liability for any risks relating to such foreign legislation. Any responsibility of TERA regarding the possible infringement of foreign laws in connection with your use of the Services from abroad is expressly and completely excluded.
|
||||
TERA shall assume no liability for losses if, for reasons for which TERA cannot be held responsible, TERA has been prevented from performing the transaction properly or on time, for example as a result of Force Majeure or measures, orders and/or decrees issued by domestic or foreign governmental authorities.
|
||||
In particular, TERA shall assume no liability for actions (e.g. declarations of Default), failure to take action or any suspension or restriction of services by any element within the blockchain. Furthermore, TERA shall assume no liability for the consequences of regulatory measures implemented by competent regulators with regard to any of the TERA Services.
|
||||
|
||||
13. TERMINATION
|
||||
|
||||
TERA reserves the right to close a TERA Wallet without prior notice immediately on the grounds of misusage particularly violations of these Terms or any applicable law.
|
||||
|
||||
14. TAXATION
|
||||
|
||||
You bear the sole responsibility to determine if your use of the Services and/or any other action or transaction related to TERA have tax implications for you.
|
||||
By using the Services, and to the extent permitted by law, you agree not to hold TERA liable for any tax liability associated with or arising from the operation of the Services or any other action or transaction related to TERA Services.
|
||||
|
||||
15. ENTIRE AGREEMENT
|
||||
|
||||
These Terms, together with any other agreements that apply to you constitute the entire and exclusive agreement between us and you regarding its subject matter, and supersede and replace any previous or contemporaneous written or oral contract, warranty, representation or understanding regarding its subject matter.
|
||||
|
||||
16. SEVERABILITY
|
||||
|
||||
If for any reason a court of competent jurisdiction finds any provision of these Terms invalid or unenforceable or illegal or contravene any rule, regulation or law of any market or regulator, that part will be deemed to have been excluded from these Terms from the beginning, and these Terms will be interpreted and enforced as though the provision had never been included and the legality or enforceability of the remaining provisions of the Terms or the legality, validity or enforceability of this provision in accordance with the law and/or regulation of any other jurisdiction, shall not be affected but should remain in full force and effect.
|
||||
|
||||
17. CHANGES TO THESE TERMS
|
||||
|
||||
The present Terms may change from time to time, including but not limited to cases of changes in our Services, in technology, in regulation and for any other case that TERA deems as appropriate to take measures. In case of a change, we will provide you with notice of such change by posting the updated Terms on our website and changing the "Last Updated" date at the bottom of these Terms. Any amended Terms shall become effective not earlier than 14 days after they are posted and shall apply prospectively to the use of the Services upon effectiveness of such changes. However, in case the changes address new functions of TERA Services or they are made for any legal reasons, they shall be of immediate effect. Upon effectiveness of the change as described above, the change of Terms shall be considered as accepted by you in case you continue using the TERA Services. Therefore, in case you do not agree to any amended Term, you must immediately cease using the TERA Services.
|
||||
|
||||
18. COMPLAINTS AND DISPUTES
|
||||
|
||||
In the event that an alleged breach, controversy, claim, dispute or difference (a Dispute) arises between you and TERA out of or in connection with these Terms and any other contractual documents (including but not limited to the validity, performance, breach or termination thereof), the parties shall seek to resolve the matter by negotiation by referring the matter first to:
|
||||
a) any member of your executive management in case of legal persons, or you personally if you are acting as a natural person;
|
||||
b) in the case of TERA, to the TERA Help Center.
|
||||
|
||||
The following information will need to be included:
|
||||
a) your name and surname;
|
||||
b) your e-mail address (or other recognition details);
|
||||
c) detailed enquiry description;
|
||||
e) the date and time that the issue arose.
|
||||
The Help Center shall:
|
||||
|
||||
* send an official response to you within 14 business days respectively;
|
||||
* try to resolve the matter as soon as reasonably possible;
|
||||
* inform you of the outcome.
|
||||
|
||||
20. DISPUTE RESOLUTION, PLACE OF JURISDICTION AND GOVERNING LAW
|
||||
|
||||
These Terms and any other applicable contractual documents shall exclusively be governed by and construed in accordance with the substantive laws of Switzerland, excluding the conflict of laws principles thereof.
|
||||
|
@ -1 +1 @@
|
||||
# ABOUT TERA TOKEN
|
||||
# ABOUT TERA COIN
|
@ -1,6 +1,9 @@
|
||||
function setCookie(name,value,days) {
|
||||
function setCookie(name,value)
|
||||
{
|
||||
var days=365;
|
||||
var expires = "";
|
||||
if (days) {
|
||||
if (days)
|
||||
{
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days*24*60*60*1000));
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
@ -8,7 +11,8 @@ function setCookie(name,value,days) {
|
||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
function getCookie(name)
|
||||
{
|
||||
var nameEQ = name + "=";
|
||||
var ca = document.cookie.split(';');
|
||||
for(var i=0;i < ca.length;i++) {
|
||||
@ -19,11 +23,13 @@ function getCookie(name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
function eraseCookie(name) {
|
||||
function eraseCookie(name)
|
||||
{
|
||||
document.cookie = name+'=; Max-Age=-99999999;';
|
||||
}
|
||||
|
||||
var show = getCookie('teracookies');
|
||||
if (!show) {
|
||||
if (!show)
|
||||
{
|
||||
setTimeout("document.getElementById('cookiesmessage').style.display = 'block';", 3000);
|
||||
}
|
@ -38,6 +38,9 @@
|
||||
//запрос исходного содержания файла
|
||||
//отображение кнопки записи и отмены (прячем кнопку редактирования)
|
||||
|
||||
if(PrevEditContent[Name])
|
||||
return;
|
||||
|
||||
var elem=ByID(Name);
|
||||
PrevEditContent[Name]=elem.innerHTML;
|
||||
var Path=EditMap[Name];
|
||||
|
BIN
Source/SITE/PIC/map-nodes.jpg
Normal file
BIN
Source/SITE/PIC/map-nodes.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 61 KiB |
@ -21,30 +21,8 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="/#about">ABOUT</a></li>
|
||||
<!--li><a href="/changelog.html">CHANGELOG</a></li-->
|
||||
<li><a href="/tera-token.html">TERA TOKEN</a></li>
|
||||
<li><a href="/tera-token.html">TERA COIN</a></li>
|
||||
<li><a href="/blog/">BLOG</a></li>
|
||||
|
||||
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -51,30 +51,9 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -51,30 +51,9 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -8,7 +8,7 @@
|
||||
<meta data-n-head="true" data-hid="description" name="description" content="Tera - Fast block generation, High transaction throughput, User-friendly">
|
||||
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
|
||||
|
||||
<title>TERA Foundation: TOKEN</title>
|
||||
<title>TERA Foundation: COIN</title>
|
||||
|
||||
<!-- Google font -->
|
||||
<link href="https://fonts.googleapis.com/css?family=Montserrat:400,700%7CVarela+Round" rel="stylesheet">
|
||||
@ -51,30 +51,9 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -51,30 +51,9 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -112,7 +91,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="#about">ÜBER TERA</a></li>
|
||||
<!--li><a href="/changelog.html" target="_blank">CHANGELISTE</a></li-->
|
||||
<li><a href="/tera-token.html" target="_blank">TERA TOKEN</a></li>
|
||||
<li><a href="/tera-token.html" target="_blank">TERA COIN</a></li>
|
||||
<li><a href="/blog/" target="_blank">BLOG</a></li>
|
||||
|
||||
|
||||
|
256
Source/SITE/emission.html
Normal file
256
Source/SITE/emission.html
Normal file
@ -0,0 +1,256 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Tera Emission</title>
|
||||
<script type="text/javascript" src="../HTML/JS/diagram.js"></script>
|
||||
|
||||
<script>
|
||||
function UpdateDiagrams()
|
||||
{
|
||||
// var Account0=529202650;
|
||||
// var BlockNumStart=22841472;
|
||||
|
||||
var Account0=Math.floor($("idAccount0Start").value);
|
||||
var BlockNumStart=Math.floor($("idBlockNumStart").value);
|
||||
var BlockNumEnd=Math.floor($("idBlockNumEnd").value);
|
||||
|
||||
var KTera=Number($("idKTera").value);
|
||||
var PERIOD_END_43=Math.floor($("idPERIOD_END_43").value);
|
||||
var PERIOD_END_45=Math.floor($("idPERIOD_END_45").value);
|
||||
|
||||
|
||||
var StepNumber=24*3600;
|
||||
var Ret=CalcReward(Account0,BlockNumStart,BlockNumEnd,StepNumber,KTera,PERIOD_END_43,PERIOD_END_45);
|
||||
|
||||
var ArrX=[];
|
||||
for(var i=0;i<Ret.BlockNum.length;i++)
|
||||
ArrX[i]=DateFromBlock(Ret.BlockNum[i]);
|
||||
|
||||
var MaxEmission=1000;
|
||||
var ArrEmission=[];
|
||||
for(var i=0;i<Ret.Account0.length;i++)
|
||||
{
|
||||
if(i<365)
|
||||
{
|
||||
if(i>=1)
|
||||
{
|
||||
ArrEmission[i]=365*(Ret.Account0[0]-Ret.Account0[i])/i;
|
||||
if(i===1)
|
||||
ArrEmission[0]=ArrEmission[i];
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrEmission[i]=0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrEmission[i]=Ret.Account0[i-365]-Ret.Account0[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DrawDiagramMy({id:"idReward",red:"#1b9031",arrX:ArrX,arr:Ret.Reward,KPrecision:100});
|
||||
DrawDiagramMy({id:"idEmission",red:"#c0465d",arrX:ArrX,arr:ArrEmission,KPrecision:10});
|
||||
DrawDiagramMy({id:"idAccount0",red:"#1e21cb",startnumber:BlockNumStart,steptime:StepNumber,arr:Ret.Account0});
|
||||
}
|
||||
function DrawDiagramMy(Item)
|
||||
{
|
||||
Item.name=Item.id;
|
||||
Item.fillStyle="#FFF";
|
||||
Item.line=1;
|
||||
if(!Item.steptime)
|
||||
Item.steptime=1;
|
||||
DiagramMapId[Item.id]=Item;
|
||||
DiagramMap[Item.name]=Item;
|
||||
DrawDiagram(Item);
|
||||
}
|
||||
|
||||
window.onload=function()
|
||||
{
|
||||
//COMMON MOUSE MOVING
|
||||
window.onmousemove = function(event)
|
||||
{
|
||||
SetDiagramMouseX(event);
|
||||
}
|
||||
|
||||
//UpdateDiagrams();
|
||||
InitDiagramByArr([]);
|
||||
};
|
||||
|
||||
function $(id)
|
||||
{
|
||||
return document.getElementById(id);
|
||||
}
|
||||
</script>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
function CalcReward(Account0,BlockNumStart,BlockNumEnd, ArrDelta, KTera, PERIOD_END_43,PERIOD_END_45)
|
||||
{
|
||||
|
||||
//old consts
|
||||
var REF_PERIOD_START=2*1000000;
|
||||
var REF_PERIOD_END=30*1000000;
|
||||
// var PERIOD_END_43=43*1000000;
|
||||
// var PERIOD_END_45=45*1000000;
|
||||
|
||||
var ArrIndex=0;
|
||||
var Ret={Reward:[],Account0:[],Emission:[],BlockNum:[]};
|
||||
|
||||
var BlockNum=BlockNumStart;
|
||||
//var KTera=3;
|
||||
var SumReward=0;
|
||||
var NumDelta=0;
|
||||
while(BlockNum<=BlockNumEnd)
|
||||
{
|
||||
var Reward=Account0*43*43/100/1000000000;
|
||||
if(BlockNum<=REF_PERIOD_END)
|
||||
{
|
||||
Reward=Account0*43*43/100/1000000000;
|
||||
var K=(REF_PERIOD_END-BlockNum)/(REF_PERIOD_END-REF_PERIOD_START);
|
||||
if(K>0)
|
||||
Reward+=2*K*Reward;
|
||||
}
|
||||
else
|
||||
if(BlockNum<=PERIOD_END_43)
|
||||
{
|
||||
Reward=Account0*43*43/100/1000000000;
|
||||
|
||||
var K=(PERIOD_END_45-BlockNum)/(PERIOD_END_45-REF_PERIOD_END);
|
||||
Reward=K*Reward
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Reward=KTera*Account0/1000000000;
|
||||
}
|
||||
|
||||
|
||||
SumReward=SumReward+Reward;
|
||||
Account0-=Reward;
|
||||
|
||||
|
||||
|
||||
//stat
|
||||
NumDelta++;
|
||||
if(NumDelta>=ArrDelta)
|
||||
{
|
||||
|
||||
Ret.Reward[ArrIndex]=Reward;
|
||||
Ret.Account0[ArrIndex]=Account0/1000000;
|
||||
//Ret.Emission[ArrIndex]=SumReward/1000000;
|
||||
Ret.BlockNum[ArrIndex]=BlockNum;
|
||||
ArrIndex++;
|
||||
|
||||
//console.log(""+DateFromBlock(BlockNum)+" = "+Reward+" SUM:"+Math.floor(SumReward)+"/"+Math.floor(Account0));
|
||||
NumDelta=0;
|
||||
SumReward=0;
|
||||
}
|
||||
BlockNum++;
|
||||
}
|
||||
return Ret;
|
||||
}
|
||||
|
||||
|
||||
function formatDate(now)
|
||||
{
|
||||
var year=now.getFullYear();
|
||||
var month=now.getMonth()+1;
|
||||
var date=now.getDate();
|
||||
return year+"-"+String(month).padStart(2,"0")+"-"+String(date).padStart(2,"0");
|
||||
}
|
||||
function DateFromBlock(BlockNum)
|
||||
{
|
||||
var Str;
|
||||
var FIRST_TIME_BLOCK=1530446400000;
|
||||
var now = new Date(FIRST_TIME_BLOCK + BlockNum * 1000);
|
||||
Str = formatDate(now);
|
||||
return Str;
|
||||
};
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<h3>The parameters of the economy</h3>
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD>
|
||||
Point 43:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idPERIOD_END_43" style="width:120px" value="43000000">
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>
|
||||
Point 45:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idPERIOD_END_45" style="width:120px" value="45500000">
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>
|
||||
KTera:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idKTera" style="width:120px" value="3">
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
|
||||
|
||||
</TABLE>
|
||||
|
||||
<h3>The parameters of view</h3>
|
||||
<TABLE>
|
||||
<TR>
|
||||
<TD>
|
||||
Start BlockNum:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idBlockNumStart" style="width:120px" value="22841472">
|
||||
</TD>
|
||||
</TR>
|
||||
<TR>
|
||||
<TD>
|
||||
Start Account0:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idAccount0Start" style="width:120px" value="529202650">
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
End BlockNum:
|
||||
</TD>
|
||||
<TD>
|
||||
<INPUT type="number" id="idBlockNumEnd" style="width:120px" value="100000000">
|
||||
</TD>
|
||||
</TR>
|
||||
|
||||
<TR>
|
||||
<TD>
|
||||
<button onclick="UpdateDiagrams()">SHOW DIAGRAMS</button>
|
||||
</TD>
|
||||
</TR>
|
||||
</TABLE>
|
||||
|
||||
|
||||
<h4 >Reward, TERA per block</h4>
|
||||
<canvas class="DIAGRAM" width='1100' height='200' id='idReward'></canvas>
|
||||
|
||||
<h4 >Emission, Million TERA per Year</h4>
|
||||
<canvas class="DIAGRAM" width='1100' height='200' id='idEmission'></canvas>
|
||||
|
||||
<h4 >Balance of account 0, Million TERA</h4>
|
||||
<canvas class="DIAGRAM" width='1100' height='200' id='idAccount0'></canvas>
|
||||
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -286,10 +265,10 @@ We will create a roadmap in more detail in the near future.
|
||||
|
||||
<hr />
|
||||
<p>
|
||||
<strong><span class="faqa">Will it take one common IP address per node in the future?
|
||||
<strong><span class="faqa">Will it take one public IP address per node in the future?
|
||||
</span></strong>
|
||||
|
||||
<p>Yes.
|
||||
<p>Yes. TERA is not just a decentralized network - it is a distributed network. So we need to have a lot of public addresses.
|
||||
|
||||
|
||||
</p>
|
||||
|
@ -42,9 +42,10 @@
|
||||
Project Founder Email: <a href="mailto: progr76@gmail.com" style="font-size: 14px;">progr76@gmail.com</a>.
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="terms-and-conditions.html">Terms and Conditions</a> | <a href="privacy-policy.html">Privacy Policy</a><br /><br />TERA Foundation, 2018 — 2019.
|
||||
<a href="terms-and-conditions.html">Terms and Conditions</a> | <a href="privacy-policy.html">Privacy Policy</a> | <a href="/admin" style="font-size: 14px;">admin</a> | <a href="/blog/reload" style="font-size: 14px;">reload</a><br /><br />TERA Foundation, 2017 — 2019.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Row -->
|
||||
|
||||
</div>
|
||||
|
@ -18,31 +18,9 @@
|
||||
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.6.3/css/all.css" integrity="sha384-UHRtZLI+pbxtHCWp1t77Bi1L4ZtiqrqD80Kn4Z8NTSRyMA2Fd33n5dQ8lWUE00s/" crossorigin="anonymous">
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -78,7 +56,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="#about">ABOUT</a></li>
|
||||
<!--li><a href="/changelog.html">CHANGELOG</a></li-->
|
||||
<li><a href="/tera-token.html">TERA TOKEN</a></li>
|
||||
<li><a href="/tera-token.html">TERA COIN</a></li>
|
||||
<li><a href="/blog/">BLOG</a></li>
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@
|
||||
{{Edit=./SITE/CONTENT/en-index-about-title.md}}
|
||||
</div>
|
||||
<p class="tera-logo-panel">
|
||||
<img src="PIC/Tera_Logo.png" width="240" />
|
||||
<img src="PIC/map-nodes.jpg" width="623" height="332"/>
|
||||
</p>
|
||||
{{Edit=./SITE/CONTENT/en-index-about-text.md}}
|
||||
<p class="tera-logo-panel">
|
||||
@ -113,51 +113,6 @@
|
||||
<!-- /Container -->
|
||||
|
||||
</div>
|
||||
<div id="lastnews" class="section md-padding bg-grey">
|
||||
|
||||
<!-- Container -->
|
||||
<div class="container">
|
||||
|
||||
<!-- Row -->
|
||||
<div class="row">
|
||||
|
||||
<!-- Section header -->
|
||||
<div class="section-header">
|
||||
<h2>Latest News</h2>
|
||||
</div>
|
||||
<div class="col-md-4">
|
||||
<div class="about bg-grey last-news-panel">
|
||||
<img src="/blog/uploads/1/1_1.png" alt="Rewarding authors of articles for the TERA Content Fund" />
|
||||
<p>11-March-2019</p>
|
||||
<a href="/blog/5-rewarding-authors-of-articles-for-the-tera-fontent-fund.html">Rewarding authors of articles for the TERA Content Fund</a>
|
||||
<p>We are pleased to inform you that we are rewarding two authors of articles...</p>
|
||||
</div>
|
||||
<p><button type="button" onclick="location.href='/blog/5-rewarding-authors-of-articles-for-the-tera-fontent-fund.html';" class="btn btn-secondary news-btn">READ MORE</button></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="about bg-grey last-news-panel">
|
||||
<img src="/blog/uploads/1/1_1.png" alt="TERA Blockchain News" />
|
||||
<p>10-March-2019</p>
|
||||
<a href="/blog/4-tera-blockchain-news.html">TERA Blockchain News</a>
|
||||
<p>With the large amounts of data that will inevitably occur at 1000 tps, new users should be able to quickly download the blockchain to validate it and start working with it.</p>
|
||||
</div>
|
||||
<p><button type="button" onclick="location.href='/blog/4-tera-blockchain-news.html';" class="btn btn-secondary news-btn">READ MORE</button></p>
|
||||
</div>
|
||||
|
||||
<div class="col-md-4">
|
||||
<div class="about bg-grey last-news-panel">
|
||||
<img src="/blog/uploads/3/3_1.jpg" alt="TERA Frequently Asked Questions Section" />
|
||||
<p>07-March-2019</p>
|
||||
<a href="/blog/3-tera-faq-section.html">TERA Frequently Asked Questions Section</a>
|
||||
<p>Today, the community receives many questions from various user groups, and in this regard, it was decided to create an Frequently Asked Questions section on the site.</p>
|
||||
</div>
|
||||
<p><button type="button" onclick="location.href='/blog/3-tera-faq-section.html';" class="btn btn-secondary news-btn">READ MORE</button></p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Specification -->
|
||||
<div id="technology" class="section md-padding bg-grey">
|
||||
@ -169,8 +124,8 @@
|
||||
<div class="row">
|
||||
|
||||
<!-- Section header -->
|
||||
<div class="section-header">
|
||||
<h2>Technology</h2>
|
||||
<div class="section-header text-center">
|
||||
<h2>Specification</h2>
|
||||
</div>
|
||||
<!-- /Section header -->
|
||||
<div class="no-more-tables">
|
||||
@ -230,6 +185,25 @@
|
||||
</div>
|
||||
<!-- /Specification -->
|
||||
|
||||
<!-- News-->
|
||||
<div id="lastnews" class="section md-padding bg-grey">
|
||||
|
||||
<!-- Container -->
|
||||
<div class="container">
|
||||
|
||||
<!-- Row -->
|
||||
<div class="row">
|
||||
|
||||
<!-- Section header -->
|
||||
<div class="no-more-tables">
|
||||
{{Edit=./SITE/CONTENT/en-index-lastnews.md}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- /News-->
|
||||
|
||||
<!-- Updates -->
|
||||
<div id="updates" class="section md-padding">
|
||||
|
||||
@ -239,14 +213,9 @@
|
||||
<!-- Row -->
|
||||
<div class="row">
|
||||
|
||||
<!-- Section header -->
|
||||
<div class="section-header">
|
||||
<h2>Updates</h2>
|
||||
</div>
|
||||
<!-- /Section header -->
|
||||
<div class="no-more-tables">
|
||||
{{Edit=./SITE/CONTENT/en-index-changelog.md5}}
|
||||
<p><a href="/changelog.html">Full Changelog</a></p>
|
||||
{{Edit=./SITE/CONTENT/en-index-changelog.md}}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -350,13 +319,14 @@
|
||||
</div>
|
||||
<div class="roadmap-item__body ">
|
||||
<div class="roadmap-item__date">
|
||||
Q1 2019
|
||||
2019
|
||||
</div>
|
||||
<div class="roadmap-item__info">
|
||||
<ul>
|
||||
<li>
|
||||
Android/iOS wallets
|
||||
</li>
|
||||
<li>Create and promote TERA Dapps</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
@ -364,6 +334,8 @@
|
||||
</div>
|
||||
<!-- /Roadmap Item -->
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
@ -393,12 +365,8 @@
|
||||
|
||||
<h3><i class="fas fa-code linksico"></i> FOR DEVELOPERS</h3>
|
||||
|
||||
1. <a href="https://sourceforge.net/p/tera/code/ci/master/tree/" target="_blank">TERA Source Code</a>.<br />
|
||||
2. <a href="https://docs.google.com/document/d/1PXVBbMKdpsAKPkO9UNB5B-LMwIDjylWoHvAAzzrXjvU/edit?usp=sharing/" target="_blank">TERA DApp PAPER (ENG)</a>.<br />
|
||||
3. <a href="https://docs.google.com/document/d/1SkD4yc_POaGRMJRC6yGkDfdJUuKbcyq3JpG0cBXeYGM/edit?usp=sharing/" target="_blank">TERA DApp PAPER (RUS)</a>.<br />
|
||||
4. <a href="https://docs.google.com/document/d/10yXAKxaU7YgrQnbdXu_L7WWovUoRtdJwo3tXXaGZGSQ/edit?usp=sharing/" target="_blank">TERA DApp FAQ</a>.<br />
|
||||
5. <a href="https://sourceforge.net/p/tera/code/ci/master/tree/Doc/Eng/API.md" target="_blank">TERA API</a>.<br />
|
||||
е. <a href="https://gitlab.com/terafoundation/tera/blob/master/Doc/Eng/API2.md" target="_blank">TERA API-2 (for Exchanges)</a>.<br />
|
||||
{{Edit=./SITE/CONTENT/en-index-link-1.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -407,12 +375,8 @@
|
||||
|
||||
<h3><i class="fas fa-dollar-sign linksico"></i> FOR INVESTORS</h3>
|
||||
|
||||
1. <a href="https://www.qbtc.ink/trade?symbol=TERA_BTC" target="_blank">TERA on QBTC Exchange</a>.<br />
|
||||
2. <a href="https://www.bitalong.com/trade/index/market/tera_usdt/" target="_blank">TERA on Bitalong Exchange</a>.<br />
|
||||
3. <a href="https://bitmesh.com/exchange?market=btc_tera#/" target="_blank">TERA on Bitmesh Exchange</a>.<br />
|
||||
4. <a href="https://chaoex-en-us.udesk.cn/hc/articles/83487" target="_blank">TERA on CHAOEX Exchange</a>.<br />
|
||||
5. <a href="https://www.citex.co.kr/#/trade/2/37" target="_blank">TERA on CITEX Exchange</a>.<br />
|
||||
6. <a href="/#roadmap" target="_blank">TERA Roadmap</a>.
|
||||
{{Edit=./SITE/CONTENT/en-index-link-2.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -421,8 +385,8 @@
|
||||
|
||||
<h3><i class="fas fa-server linksico"></i> FOR MINERS</h3>
|
||||
|
||||
1. <a href="https://sourceforge.net/p/tera/code/ci/master/tree/README.md" target="_blank">TERA Mining Documentation</a>.<br />
|
||||
2. <a href="https://docs.google.com/document/d/18DtASGhrbRwXCAkQR1hQG0lVdrStp4CgA-pd6hicwfo/edit?usp=sharing/" target="_blank">TERA HAASH</a>.
|
||||
{{Edit=./SITE/CONTENT/en-index-link-3.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -431,14 +395,8 @@
|
||||
|
||||
<h3><i class="fas fa-info-circle linksico"></i> TERA INFORMATION</h3>
|
||||
|
||||
1. <a href="https://terafoundation.org/" target="_blank">TERA Website</a>.<br />
|
||||
2. <a href="https://terafoundation.org/explorer.html" target="_blank">TERA EXPLORER</a>.<br />
|
||||
3. <a href="https://terafoundation.org/web-wallet.html" target="_blank">TERA WALLET</a>.<br />
|
||||
4. <a href="https://terafoundation.org/map.html" target="_blank">TERA NETWORK MAP</a>.<br />
|
||||
5. <a href="https://terafoundation.org/files/TERA_WP_EN.pdf" target="_blank">TERA WHITE PAPER (EN)</a>.<br />
|
||||
6. <a href="https://terafoundation.org/files/TERA_WP_RU.pdf" target="_blank">TERA WHITE PAPER (RU)</a>.<br />
|
||||
7. <a href="https://terafoundation.org/files/TERA_WP_DE.pdf" target="_blank">TERA WHITE PAPER (DE)</a>.<br />
|
||||
8. <a href="https://sourceforge.net/p/tera/code/ci/master/tree/Doc/Chinese/WP_chinese.pdf?format=raw" target="_blank">TERA WHITE PAPER (CN)</a>.<br />
|
||||
{{Edit=./SITE/CONTENT/en-index-link-4.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -447,12 +405,8 @@
|
||||
|
||||
<h3><i class="fas fa-globe linksico"></i> TERA COMMUNITY</h3>
|
||||
|
||||
1. <a href="https://bitcointalk.org/index.php?topic=4573801.0" target="_blank">TERA on BitcoinTalk</a>.<br />
|
||||
2. <a href="https://twitter.com/terafoundation" target="_blank">TERA on Twitter</a>.<br />
|
||||
3. <a href="https://www.reddit.com/user/Terafoundation" target="_blank">TERA on Reddit</a>.<br />
|
||||
4. <a href="https://discord.gg/CvwrbeG" target="_blank">TERA on Discord</a>.<br />
|
||||
5. <a href="https://web.telegram.org/#/im?p=@terafoundation" target="_blank">TERA Telegram Chanel</a>.<br />
|
||||
6. <a href="https://jq.qq.com/?_wv=1027&k=58VsQxc" target="_blank">TERA on QQ</a>.
|
||||
{{Edit=./SITE/CONTENT/en-index-link-5.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -461,7 +415,8 @@
|
||||
|
||||
<h3><i class="fas fa-handshake linksico"></i> OTHER</h3>
|
||||
|
||||
1. <a href="http://freetimes.cc/fmessenger/" target="_blank">FMessenger</a>.
|
||||
{{Edit=./SITE/CONTENT/en-index-link-6.md}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<!-- /About Tera content -->
|
||||
|
@ -82,7 +82,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="index.html">HOME</a></li>
|
||||
<li><a href="/changelog.html">CHANGELOG</a></li>
|
||||
<li><a href="/token.html">TOKEN</a></li>
|
||||
<li><a href="/token.html">COIN</a></li>
|
||||
<li><a href="/tera-content-fund.html">CONTENT FUND</a></li>
|
||||
<li><a href="/blog/">BLOG</a></li>
|
||||
<li><a href="/explorer.html">EXPLORER</a></li>
|
||||
|
24
Source/SITE/metrika.html
Normal file
24
Source/SITE/metrika.html
Normal file
@ -0,0 +1,24 @@
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
@ -1,7 +1,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="/#about">ABOUT</a></li>
|
||||
<!--li><a href="/changelog.html">CHANGELOG</a></li-->
|
||||
<li><a href="/tera-token.html">TERA TOKEN</a></li>
|
||||
<li><a href="/tera-token.html">TERA COIN</a></li>
|
||||
<li><a href="/blog/">BLOG</a></li>
|
||||
|
||||
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -51,30 +51,9 @@
|
||||
}
|
||||
|
||||
</style>
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<ul class="main-nav nav navbar-nav navbar-right white_menu">
|
||||
<li><a href="#about">О TERA</a></li>
|
||||
<!--li><a href="/ru/changelog.html">CHANGELOG</a></li-->
|
||||
<li><a href="/ru/tera-token.html">ТОКЕН TERA</a></li>
|
||||
<li><a href="/ru/tera-token.html">МОНЕТА TERA</a></li>
|
||||
<li><a href="/blog/" target="_blank">БЛОГ</a></li>
|
||||
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>TERA Foundation: TOKEN</title>
|
||||
<title>TERA Foundation: COIN</title>
|
||||
<meta data-n-head="true" data-hid="description" name="description" content="Tera - Fast block generation, High transaction throughput, User-friendly">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>TERA Foundation: TOKEN</title>
|
||||
<title>TERA Foundation: COIN</title>
|
||||
<meta data-n-head="true" data-hid="description" name="description" content="Tera - Fast block generation, High transaction throughput, User-friendly">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="../CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>TERA Foundation: TOKEN</title>
|
||||
<title>TERA Foundation: COIN</title>
|
||||
<meta data-n-head="true" data-hid="description" name="description" content="Tera - Fast block generation, High transaction throughput, User-friendly">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
@ -2,7 +2,7 @@
|
||||
<html lang="en">
|
||||
|
||||
<head>
|
||||
<title>TERA Foundation: TOKEN</title>
|
||||
<title>TERA Foundation: COIN</title>
|
||||
<meta data-n-head="true" data-hid="description" name="description" content="Tera - Fast block generation, High transaction throughput, User-friendly">
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
@ -21,30 +21,9 @@
|
||||
<!-- Custom stlylesheet -->
|
||||
<link type="text/css" rel="stylesheet" href="CSS/style.min.css" />
|
||||
|
||||
<!-- Yandex.Metrika counter -->
|
||||
<script type="text/javascript" >
|
||||
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
|
||||
m[i].l=1*new Date();k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
|
||||
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym");
|
||||
|
||||
ym(52744594, "init", {
|
||||
clickmap:true,
|
||||
trackLinks:true,
|
||||
accurateTrackBounce:true,
|
||||
webvisor:true
|
||||
});
|
||||
</script>
|
||||
<noscript><div><img src="https://mc.yandex.ru/watch/52744594" style="position:absolute; left:-9999px;" alt="" /></div></noscript>
|
||||
<!-- /Yandex.Metrika counter -->
|
||||
<!-- Global site tag (gtag.js) - Google Analytics -->
|
||||
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-135904501-1"></script>
|
||||
<script>
|
||||
window.dataLayer = window.dataLayer || [];
|
||||
function gtag(){dataLayer.push(arguments);}
|
||||
gtag('js', new Date());
|
||||
{{File=./SITE/metrika.html}}
|
||||
|
||||
gtag('config', 'UA-135904501-1');
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -115,7 +94,7 @@
|
||||
<!-- About Tera content -->
|
||||
<div class="col-md-12 about-panel">
|
||||
<div class="section-header text-center">
|
||||
<h1>TERA TOKEN</h1>
|
||||
<h1>TERA COIN</h1>
|
||||
</div>
|
||||
<p>
|
||||
TERA is a coin that provides solutions to existing cryptocurrency issues, namely de-neutralization, transaction
|
||||
|
@ -1293,7 +1293,7 @@ module.exports = class CConsensus extends require("./block-loader")
|
||||
if(GrayConnect())
|
||||
{
|
||||
if(!this.LoadHistoryMode)
|
||||
this.StartLoadHistory(undefined, 1)
|
||||
this.StartSyncBlockchain(undefined, 1)
|
||||
return ;
|
||||
}
|
||||
if(this.LoadHistoryMode)
|
||||
@ -1440,11 +1440,12 @@ module.exports = class CConsensus extends require("./block-loader")
|
||||
if(PrevBlock.bSave && this.BlockNumDB + 1 >= Block.BlockNum)
|
||||
{
|
||||
this.AddToStatBlockConfirmation(Block)
|
||||
var Power = GetPowPower(Block.PowHash);
|
||||
if(this.WriteBlockDB(Block))
|
||||
{
|
||||
if(Block.arrContent && Block.arrContent.length)
|
||||
ADD_TO_STAT("MAX:TRANSACTION_COUNT", Block.arrContent.length)
|
||||
AddInfoBlock(Block, "SAVE TO DB: " + GetPowPower(Block.PowHash))
|
||||
AddInfoBlock(Block, "SAVE:" + Power + " TH:" + this.GetStrFromHashShort(Block.TreeHash).substr(0, 4))
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1452,6 +1453,34 @@ module.exports = class CConsensus extends require("./block-loader")
|
||||
AddInfoBlock(Block, "ERROR WRITE DB")
|
||||
}
|
||||
this.AddToMaxSum(Block, {SumHash:Block.SumHash, SumList:this.GetBlockList(Block.BlockNum), })
|
||||
if(typeof global.RESYNC_CONDITION === "object")
|
||||
{
|
||||
if(!this.OwnBlockCount)
|
||||
this.OwnBlockCount = 0
|
||||
var Miner = ReadUintFromArr(Block.AddrHash, 0);
|
||||
var MultK = RESYNC_CONDITION.K_POW;
|
||||
var MaxBlocks = RESYNC_CONDITION.OWN_BLOCKS;
|
||||
if(Miner === GENERATE_BLOCK_ACCOUNT)
|
||||
{
|
||||
this.OwnBlockCount++
|
||||
if(this.OwnBlockCount >= MaxBlocks)
|
||||
{
|
||||
var PrevSumPow = this.GetAvgPowBlock(Block.BlockNum - 2 * MaxBlocks, MaxBlocks);
|
||||
var CurrentPow = this.GetAvgPowBlock(Block.BlockNum - MaxBlocks, MaxBlocks);
|
||||
if(CurrentPow === 0 || PrevSumPow / CurrentPow >= MultK)
|
||||
{
|
||||
ToLog("START RESYNC CONDITION")
|
||||
this.OwnBlockCount = 0
|
||||
this.StartSyncBlockchain()
|
||||
return ;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.OwnBlockCount = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1476,6 +1505,25 @@ module.exports = class CConsensus extends require("./block-loader")
|
||||
this.RelayMode = !bWasSave
|
||||
this.FREE_MEM_BLOCKS(CURRENTBLOCKNUM - BLOCK_COUNT_IN_MEMORY)
|
||||
}
|
||||
GetAvgPowBlock(StartNum, CountNum)
|
||||
{
|
||||
var Count = 0;
|
||||
var SumPow = 0;
|
||||
for(var Num = StartNum; Num < StartNum + CountNum; Num++)
|
||||
{
|
||||
var Block = this.GetBlock(Num);
|
||||
if(Block && Block.bSave)
|
||||
{
|
||||
var Power = GetPowPower(Block.PowHash);
|
||||
SumPow += Power
|
||||
Count++
|
||||
}
|
||||
}
|
||||
if(!Count)
|
||||
return 0;
|
||||
else
|
||||
return SumPow / Count;
|
||||
}
|
||||
CreatePOWNew(Block)
|
||||
{
|
||||
CreateHashMinimal(Block, GENERATE_BLOCK_ACCOUNT)
|
||||
@ -1556,12 +1604,6 @@ module.exports = class CConsensus extends require("./block-loader")
|
||||
}
|
||||
};
|
||||
global.TreeBlockBuf = new STreeBuffer(50 * 1000, CompareItemHashSimple, "string");
|
||||
global.GetCurrentBlockNumByTime = function GetCurrentBlockNumByTime()
|
||||
{
|
||||
var CurTimeNum = GetCurrentTime() - FIRST_TIME_BLOCK;
|
||||
var StartBlockNum = Math.trunc((CurTimeNum + CONSENSUS_PERIOD_TIME) / CONSENSUS_PERIOD_TIME);
|
||||
return StartBlockNum;
|
||||
};
|
||||
var PrevTimeIdle = 0;
|
||||
OnTimeIdle();
|
||||
|
||||
|
16
Source/core/block-loader-const.js
Normal file
16
Source/core/block-loader-const.js
Normal file
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
||||
global.PERIOD_GET_BLOCK = 300, global.COUNT_HISTORY_BLOCKS_FOR_LOAD = 600, global.COUNT_BLOCKS_FOR_CHECK_POW = 50, global.MAX_DELTA_COUNT_SUM_FOR_LOAD = 10,
|
||||
global.MAX_COUNT_CHAIN_LOAD = 120, global.PACKET_ALIVE_PERIOD = 4 * CONSENSUS_PERIOD_TIME, global.PACKET_ALIVE_PERIOD_NEXT_NODE = PACKET_ALIVE_PERIOD / 2,
|
||||
global.MAX_BLOCK_SEND = 8, global.COUNT_TASK_FOR_NODE = 10, global.FORMAT_BLOCK_TRANSFER = "{ BlockNum:uint, TreeHash:hash, arrContent:[tr], }",
|
||||
global.WRK_BLOCK_TRANSFER = {}, global.MAX_ACCOUNTS_TRANSFER = 1e3, global.MAX_SMARTS_TRANSFER = 10, global.TEST_NETWORK && (global.MAX_ACCOUNTS_TRANSFER = 100,
|
||||
global.MAX_SMARTS_TRANSFER = 10), global.FORMAT_REST_TRANSFER = "{ Result:uint, BlockNum:uint, Arr:[arr200], }",
|
||||
global.FORMAT_SMART_TRANSFER = "{ Result:uint, Arr:[tr], }";
|
@ -11,27 +11,9 @@
|
||||
"use strict";
|
||||
const fs = require("fs");
|
||||
const crypto = require('crypto');
|
||||
require('./block-loader-const');
|
||||
const STAT_BLOCK_LOAD_PERIOD = CONSENSUS_PERIOD_TIME / 5;
|
||||
global.PERIOD_GET_BLOCK = 300;
|
||||
if(global.LOCAL_RUN || global.TEST_NETWORK)
|
||||
{
|
||||
global.COUNT_BLOCKS_FOR_LOAD = global.DELTA_BLOCK_ACCOUNT_HASH / 2;
|
||||
}
|
||||
global.COUNT_HISTORY_BLOCKS_FOR_LOAD = 600;
|
||||
global.COUNT_BLOCKS_FOR_CHECK_POW = 50;
|
||||
global.MAX_DELTA_COUNT_SUM_FOR_LOAD = 10;
|
||||
global.MAX_COUNT_CHAIN_LOAD = 120;
|
||||
global.PACKET_ALIVE_PERIOD = 4 * CONSENSUS_PERIOD_TIME;
|
||||
global.PACKET_ALIVE_PERIOD_NEXT_NODE = PACKET_ALIVE_PERIOD / 2;
|
||||
global.MAX_BLOCK_SEND = 8;
|
||||
global.COUNT_TASK_FOR_NODE = 10;
|
||||
const Formats = {BLOCK_TRANSFER:"{\
|
||||
BlockNum:uint,\
|
||||
TreeHash:hash,\
|
||||
arrContent:[tr],\
|
||||
}",
|
||||
WRK_BLOCK_TRANSFER:{}, };
|
||||
module.exports = class CBlock extends require("./db/block-db")
|
||||
module.exports = class CBlock extends require("./rest-loader.js")
|
||||
{
|
||||
constructor(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
||||
{
|
||||
@ -145,7 +127,7 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
var PrevHash = CalcHashFromArray(arr, true);
|
||||
return PrevHash;
|
||||
}
|
||||
StartLoadHistory(Node, bSilent)
|
||||
StartSyncBlockchain(Node, bSilent, bCheckPoint)
|
||||
{
|
||||
this.FREE_ALL_MEM_CHAINS()
|
||||
if(global.NO_HISTORY_MODE)
|
||||
@ -163,11 +145,15 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
this.RelayMode = true
|
||||
this.LoadHistoryMode = true
|
||||
this.LoadHistoryMessage = !bSilent
|
||||
this.LoadHistoryContext = {Node:Node, BlockNum:this.BlockNumDB, MapSend:{}, Foward:1, Pause:0, DeltaBlockNum:10}
|
||||
this.LoadHistoryContext = {PrevBlockNum: - 1, Node:Node, BlockNum:this.BlockNumDB, MapSend:{}, Foward:1, Pause:0, DeltaBlockNum:10,
|
||||
StartTimeHistory:Date.now(), MaxTimeOut:30 * 1000}
|
||||
if(!bSilent && !bCheckPoint && REST_START_COUNT)
|
||||
{
|
||||
this.CheckSyncRest()
|
||||
}
|
||||
if(!this.ActualNodes.size)
|
||||
{
|
||||
ToLog("There is no connections to other nodes")
|
||||
return ;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -177,6 +163,60 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
}
|
||||
}
|
||||
}
|
||||
LoopSyncBlockchain()
|
||||
{
|
||||
if(!this.ActualNodes.size)
|
||||
return ;
|
||||
var Context;
|
||||
if(this.LoadRestContext && this.LoadRestContext.Mode < 200)
|
||||
Context = this.LoadRestContext
|
||||
else
|
||||
Context = this.LoadHistoryContext
|
||||
if(Context.PrevBlockNum === Context.BlockNum)
|
||||
{
|
||||
var DeltaTime = Date.now() - Context.StartTimeHistory;
|
||||
if(DeltaTime > Context.MaxTimeOut)
|
||||
{
|
||||
ToLog("DETECT TIMEOUT LOAD")
|
||||
this.StartSyncBlockchain()
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.PrevBlockNum = Context.BlockNum
|
||||
Context.StartTimeHistory = Date.now()
|
||||
}
|
||||
if(Context.LoopSyncRest)
|
||||
{
|
||||
this.LoopSyncRest()
|
||||
return ;
|
||||
}
|
||||
if(Context.Pause)
|
||||
{
|
||||
if(this.LoadedChainList.length)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
Context.Pause = 0
|
||||
Context.BlockNum = this.BlockNumDB
|
||||
}
|
||||
var BlockDB = this.ReadBlockHeaderDB(Context.BlockNum);
|
||||
if(!BlockDB || this.BlockNumDB >= GetCurrentBlockNumByTime() - BLOCK_PROCESSING_LENGTH - 2)
|
||||
{
|
||||
this.LoadHistoryMode = false
|
||||
if(this.LoadHistoryMessage)
|
||||
ToLog("Finish synchronization")
|
||||
if(!BlockDB)
|
||||
return ;
|
||||
}
|
||||
var Ret = this.GetNextNode(Context, Context.BlockNum, 1);
|
||||
if(Ret.Result)
|
||||
{
|
||||
var Node = Ret.Node;
|
||||
this.SendF(Node, {"Method":"GETBLOCKHEADER", "Context":Context, "Data":{Foward:1, BlockNum:Context.BlockNum, Hash:BlockDB.SumHash}})
|
||||
}
|
||||
}
|
||||
StartLoadBlockHeader(LoadHash, Num, StrInfo, bIsSum)
|
||||
{
|
||||
if(this.LoadHistoryMode)
|
||||
@ -208,51 +248,6 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
}
|
||||
return true;
|
||||
}
|
||||
LoopHistoryLoad()
|
||||
{
|
||||
if(!this.ActualNodes.size)
|
||||
return ;
|
||||
var Context = this.LoadHistoryContext;
|
||||
if(Context.PrevBlockNum === Context.BlockNum)
|
||||
{
|
||||
var DeltaTime = Date.now() - Context.StartTimeHistory;
|
||||
if(DeltaTime > 30 * 1000)
|
||||
{
|
||||
ToLog("DETECT TIMEOUT LOADHISTORY")
|
||||
this.StartLoadHistory()
|
||||
return ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.PrevBlockNum = Context.BlockNum
|
||||
Context.StartTimeHistory = Date.now()
|
||||
}
|
||||
if(Context.Pause)
|
||||
{
|
||||
if(this.LoadedChainList.length)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
Context.Pause = 0
|
||||
Context.BlockNum = this.BlockNumDB
|
||||
}
|
||||
var BlockDB = this.ReadBlockHeaderDB(Context.BlockNum);
|
||||
if(!BlockDB || this.BlockNumDB >= GetCurrentBlockNumByTime() - BLOCK_PROCESSING_LENGTH - 2)
|
||||
{
|
||||
this.LoadHistoryMode = false
|
||||
if(this.LoadHistoryMessage)
|
||||
ToLog("Finish synchronization")
|
||||
if(!BlockDB)
|
||||
return ;
|
||||
}
|
||||
var Ret = this.GetNextNode(Context, Context.BlockNum, 1);
|
||||
if(Ret.Result)
|
||||
{
|
||||
var Node = Ret.Node;
|
||||
this.SendF(Node, {"Method":"GETBLOCKHEADER", "Context":Context, "Data":{Foward:1, BlockNum:Context.BlockNum, Hash:BlockDB.SumHash}})
|
||||
}
|
||||
}
|
||||
SetChainNum(chain)
|
||||
{
|
||||
if(!chain.id)
|
||||
@ -270,12 +265,12 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
this.TruncateBlockDB(this.UseTruncateBlockDB)
|
||||
if(this.LoadHistoryMode)
|
||||
{
|
||||
this.LoopHistoryLoad()
|
||||
this.LoopSyncBlockchain()
|
||||
return ;
|
||||
}
|
||||
if(this.BlockNumDB < this.CurrentBlockNum - BLOCK_PROCESSING_LENGTH2)
|
||||
{
|
||||
this.StartLoadHistory()
|
||||
this.StartSyncBlockchain()
|
||||
return ;
|
||||
}
|
||||
var CountStopSend = 0;
|
||||
@ -502,6 +497,12 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
bFindDB = 1
|
||||
arr2.push(Block)
|
||||
}
|
||||
else
|
||||
if(BlockDB && IsZeroArr(BlockDB.SumHash))
|
||||
{
|
||||
bFindDB = 1
|
||||
arr2.push(Block)
|
||||
}
|
||||
}
|
||||
else
|
||||
if(bFindDB)
|
||||
@ -832,12 +833,14 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
var Block, FirstBlock;
|
||||
for(var i = 0; i < arr.length; i++)
|
||||
{
|
||||
if(arr[i].BlockNum > this.BlockNumDB + 1)
|
||||
break;
|
||||
Block = arr[i]
|
||||
if(Block.BlockNum > this.BlockNumDB + 1)
|
||||
break;
|
||||
if(!FirstBlock)
|
||||
FirstBlock = Block
|
||||
Block.BlockDown = undefined
|
||||
if(Block.BlockNum > this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
{
|
||||
var PrevHash = this.GetPrevHashDB(Block);
|
||||
if(CompareArr(PrevHash, Block.PrevHash) !== 0)
|
||||
{
|
||||
@ -846,6 +849,7 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
this.FREE_ALL_MEM_CHAINS()
|
||||
return ;
|
||||
}
|
||||
}
|
||||
var Res = 0;
|
||||
if(Block.TreeEq)
|
||||
{
|
||||
@ -883,7 +887,9 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
}
|
||||
var BlockMem = this.BlockChain[Block.BlockNum];
|
||||
if(BlockMem)
|
||||
AddInfoBlock(BlockMem, "Load:" + GetPowPower(Block.PowHash))
|
||||
{
|
||||
AddInfoBlock(BlockMem, "LOAD:" + GetPowPower(Block.PowHash) + " TH:" + this.GetStrFromHashShort(Block.TreeHash).substr(0, 4))
|
||||
}
|
||||
}
|
||||
if(Block && FirstBlock)
|
||||
{
|
||||
@ -1076,7 +1082,7 @@ module.exports = class CBlock extends require("./db/block-db")
|
||||
var Block = Info.Context.Block;
|
||||
if(Block && !Block.TreeEq)
|
||||
{
|
||||
var Data = BufLib.GetObjectFromBuffer(Info.Data, Formats.BLOCK_TRANSFER, Formats.WRK_BLOCK_TRANSFER);
|
||||
var Data = BufLib.GetObjectFromBuffer(Info.Data, FORMAT_BLOCK_TRANSFER, WRK_BLOCK_TRANSFER);
|
||||
Info.Data = undefined
|
||||
if(Data.BlockNum !== Block.BlockNum || CompareArr(Data.TreeHash, Block.TreeHash) !== 0)
|
||||
{
|
||||
@ -1429,106 +1435,41 @@ function GetFindDB()
|
||||
this.SetChainNum(chain)
|
||||
this.PrepareTransactionsForLoad(chain, arr, 1)
|
||||
}
|
||||
static
|
||||
GETREST_F()
|
||||
};
|
||||
global.LoadBlockFromNetwork = function (Params,F)
|
||||
{
|
||||
return "{\
|
||||
BlockNum:uint,\
|
||||
StartAccount:uint,\
|
||||
LengthAccount:uint,\
|
||||
}";
|
||||
}
|
||||
static
|
||||
RETREST_F()
|
||||
var BlockNum = Params.BlockNum;
|
||||
if(BlockNum >= SERVER.BlockNumDBMin)
|
||||
{
|
||||
return "{\
|
||||
Result:uint,\
|
||||
BlockNum:uint,\
|
||||
Arr:[arr200],\
|
||||
}";
|
||||
}
|
||||
GetRestAcc(Node, Delta)
|
||||
{
|
||||
var BlockNumRest = GetCurrentRestNum(Delta);
|
||||
this.SendF(Node, {"Method":"GETREST", "Context":{BlockNum:BlockNumRest}, "Data":{BlockNum:BlockNumRest, StartAccount:0}})
|
||||
return BlockNumRest;
|
||||
}
|
||||
GETREST(Info, CurTime)
|
||||
{
|
||||
var Data = this.DataFromF(Info);
|
||||
if(!Data.BlockNum)
|
||||
ToLog("Cant LoadBlockFromNetwork:" + BlockNum, 2);
|
||||
F(1);
|
||||
return ;
|
||||
var BlockNumRest = Data.BlockNum;
|
||||
var arr = GetCurrentRestArr();
|
||||
var BufLength;
|
||||
var nResult = 0;
|
||||
for(var i = 0; i < arr.length; i++)
|
||||
{
|
||||
if(arr[i] === BlockNumRest)
|
||||
{
|
||||
nResult = 1
|
||||
break;
|
||||
}
|
||||
ToLog("DownloadBlockFromNetwork:" + BlockNum, 2);
|
||||
var TaskLoadBlockFromNetwork = {MapSend:{}};
|
||||
var Ret = SERVER.GetNextNode(TaskLoadBlockFromNetwork, BlockNum, 1);
|
||||
if(Ret.Result)
|
||||
{
|
||||
let Node = Ret.Node;
|
||||
SERVER.SendF(Node, {"Method":"GETBLOCK", "Data":{BlockNum:BlockNum, TreeHash:[]}, "Context":{F:function (Info)
|
||||
{
|
||||
var Block = BufLib.GetObjectFromBuffer(Info.Data, FORMAT_BLOCK_TRANSFER, WRK_BLOCK_TRANSFER);
|
||||
Info.Data = undefined;
|
||||
if(Block.BlockNum !== BlockNum)
|
||||
{
|
||||
ToLog("Error get BlockNum:" + BlockNum + " from " + NodeName(Info.Node), 2);
|
||||
F(1);
|
||||
return ;
|
||||
}
|
||||
var ArrRest = [];
|
||||
if(nResult)
|
||||
{
|
||||
var WorkStruct = {};
|
||||
var WorkFormat = DApps.Accounts.FORMAT_ACCOUNT_ROW;
|
||||
var WorkFormatLength = DApps.Accounts.SIZE_ACCOUNT_ROW;
|
||||
var Max = DApps.Accounts.DBState.GetMaxNum();
|
||||
var FindItem;
|
||||
for(var Num = 0; Num <= Max; Num++)
|
||||
{
|
||||
FindItem = undefined
|
||||
var RestData = DApps.Accounts.ReadRest(Num);
|
||||
var Data = DApps.Accounts.DBState.Read(Num);
|
||||
if(!Data)
|
||||
break;
|
||||
var CountZero = 0;
|
||||
for(var i = RestData.Arr.length - 1; i >= 0; i--)
|
||||
{
|
||||
var Item = RestData.Arr[i];
|
||||
if(!Item.BlockNum)
|
||||
{
|
||||
CountZero++
|
||||
continue;
|
||||
}
|
||||
if(Item.BlockNum <= BlockNumRest)
|
||||
{
|
||||
if(!FindItem || Item.BlockNum > FindItem.BlockNum)
|
||||
{
|
||||
FindItem = Item
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FindItem)
|
||||
{
|
||||
Data.Value = FindItem.Value
|
||||
ToLog("Got BlockFromNetwork:" + BlockNum, 2);
|
||||
SERVER.WriteBlockDB(Block);
|
||||
F(0, Block);
|
||||
}}, });
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CountZero !== RestData.Arr.length)
|
||||
continue;
|
||||
}
|
||||
var Buf = BufLib.GetBufferFromObject(Data, WorkFormat, WorkFormatLength, WorkStruct);
|
||||
ArrRest.push(Buf)
|
||||
}
|
||||
BufLength = 1000 + ArrRest.length * WorkFormatLength
|
||||
}
|
||||
else
|
||||
{
|
||||
BufLength = 1000
|
||||
}
|
||||
this.SendF(Info.Node, {"Method":"RETREST", "Context":Info.Context, "Data":{Result:nResult, BlockNum:BlockNumRest, Arr:ArrRest}},
|
||||
BufLength)
|
||||
}
|
||||
RETREST(Info, CurTime)
|
||||
{
|
||||
var Data = this.DataFromF(Info);
|
||||
if(!Data.BlockNum || Data.BlockNum !== Info.Context.BlockNum)
|
||||
return ;
|
||||
ToLog("Get Rest on: " + Data.BlockNum + " Arr=" + Data.Arr.length)
|
||||
ToLog("Not find node for download block", 2);
|
||||
F(1);
|
||||
}
|
||||
};
|
||||
global.HistoryBlockBuf = new STreeBuffer(HISTORY_BLOCK_COUNT * 1000, CompareItemHashSimple, "string");
|
||||
|
@ -372,14 +372,16 @@ module.exports = class CConnect extends require("./transfer-msg")
|
||||
var SignArr = arr2(Data.CheckPoint.Hash, GetArrFromValue(Data.CheckPoint.BlockNum));
|
||||
if(CheckDevelopSign(SignArr, Data.CheckPoint.Sign))
|
||||
{
|
||||
this.ResetNextPingAllNode()
|
||||
global.CHECK_POINT = Data.CheckPoint
|
||||
this.ResetNextPingAllNode()
|
||||
if(Data.CheckPoint.BlockNum < this.BlockNumDBMin)
|
||||
return ;
|
||||
var Block = this.ReadBlockHeaderDB(CHECK_POINT.BlockNum);
|
||||
if(Block && CompareArr(Block.Hash, CHECK_POINT.Hash) !== 0)
|
||||
{
|
||||
this.BlockNumDB = CHECK_POINT.BlockNum - 1
|
||||
this.TruncateBlockDB(this.BlockNumDB)
|
||||
this.StartLoadHistory(Node)
|
||||
this.StartSyncBlockchain(Node, 0, 1)
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -423,7 +425,7 @@ module.exports = class CConnect extends require("./transfer-msg")
|
||||
{
|
||||
Node.VersionOK = false
|
||||
}
|
||||
if(Node.VersionOK && !Data.LoadHistoryMode)
|
||||
if(Node.VersionOK)
|
||||
{
|
||||
Node.CanHot = true
|
||||
if(CHECK_POINT.BlockNum && Data.CheckPoint.BlockNum)
|
||||
|
@ -8,8 +8,8 @@
|
||||
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
||||
*/
|
||||
|
||||
global.UPDATE_CODE_VERSION_NUM = 925;
|
||||
global.MIN_CODE_VERSION_NUM = 920;
|
||||
global.UPDATE_CODE_VERSION_NUM = 992;
|
||||
global.MIN_CODE_VERSION_NUM = 922;
|
||||
global.MINING_VERSION_NUM = 3;
|
||||
global.InitParamsArg = InitParamsArg;
|
||||
global.CONST_NAME_ARR = ["AUTO_CORRECT_TIME", "DELTA_CURRENT_TIME", "COMMON_KEY", "NODES_NAME", "SERVER_PRIVATE_KEY_HEX", "USE_NET_FOR_SERVER_ADDRES",
|
||||
@ -18,10 +18,8 @@ global.CONST_NAME_ARR = ["AUTO_CORRECT_TIME", "DELTA_CURRENT_TIME", "COMMON_KEY"
|
||||
"USE_MINING", "MINING_START_TIME", "MINING_PERIOD_TIME", "POW_MAX_PERCENT", "COUNT_MINING_CPU", "SIZE_MINING_MEMORY", "POW_RUN_COUNT",
|
||||
"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", "COREY_WATCH_DOG", "MAX_CONNECTIONS_COUNT",
|
||||
"TRUST_PROCESS_COUNT", "TRUST_BLOCKS_COUNT", ];
|
||||
global.REST_BLOCK_SCALE = 1000;
|
||||
global.TRUST_BLOCKS_COUNT = 3600;
|
||||
"HTTPS_HOSTING_DOMAIN", "HTTP_MAX_COUNT_ROWS", "HTTP_ADMIN_PASSORD", "WATCHDOG_BADACCOUNT", "RESYNC_CONDITION", "MAX_CONNECTIONS_COUNT",
|
||||
"TRUST_PROCESS_COUNT", "REST_START_COUNT", ];
|
||||
global.USE_HARD_API_V2 = 0;
|
||||
global.USE_TICKET = 0;
|
||||
global.USE_CHECK_SENDING = 1;
|
||||
@ -30,8 +28,9 @@ global.TR_TICKET_HASH_LENGTH = 10;
|
||||
global.BLOCKNUM_TICKET_ALGO = 16070000;
|
||||
global.WATCHDOG_BADACCOUNT = 1;
|
||||
global.WATCHDOG_DEV = 0;
|
||||
global.COREY_WATCH_DOG = 0;
|
||||
global.WATCHDOG_ORPHAN = 0;
|
||||
global.RESYNC_CONDITION = {"OWN_BLOCKS":10, "K_POW":10};
|
||||
global.REST_BLOCK_SCALE = 1000;
|
||||
global.REST_START_COUNT = 0;
|
||||
global.DEBUG_WALLET = 0;
|
||||
global.CHECK_GLOBAL_TIME = 1;
|
||||
global.AUTO_CORRECT_TIME = 1;
|
||||
@ -74,6 +73,7 @@ global.MIN_POWER_POW_HANDSHAKE = 12;
|
||||
global.USE_HINT = 0;
|
||||
global.ALL_VIEW_ROWS = 0;
|
||||
global.COUNT_BLOCK_PROOF = 300;
|
||||
global.COUNT_NODE_PROOF = 10;
|
||||
global.MIN_POWER_POW_MSG = 2;
|
||||
global.MEM_POOL_MSG_COUNT = 1000;
|
||||
global.MAX_LEVEL_SPECIALIZATION = 24;
|
||||
@ -107,6 +107,7 @@ global.REF_PERIOD_MINING = 1 * 1000 * 1000;
|
||||
global.DELTA_BLOCK_ACCOUNT_HASH = 1000;
|
||||
global.PERIOD_ACCOUNT_HASH = 50;
|
||||
global.START_BLOCK_ACCOUNT_HASH = 14500000;
|
||||
global.START_BLOCK_ACCOUNT_HASH3 = 24015000;
|
||||
global.NEW_ACCOUNT_INCREMENT = 22305000;
|
||||
global.NEW_BLOCK_REWARD1 = 22500000;
|
||||
global.NEW_BLOCK_REWARD2 = 30000000;
|
||||
@ -136,6 +137,7 @@ if(global.LOCAL_RUN)
|
||||
global.DELTA_BLOCK_ACCOUNT_HASH = 30;
|
||||
global.PERIOD_ACCOUNT_HASH = 10;
|
||||
global.START_BLOCK_ACCOUNT_HASH = 1;
|
||||
global.START_BLOCK_ACCOUNT_HASH3 = 1;
|
||||
global.BLOCKNUM_TICKET_ALGO = 1;
|
||||
global.SMART_BLOCKNUM_START = 0;
|
||||
global.START_MINING = 60;
|
||||
@ -147,6 +149,7 @@ if(global.LOCAL_RUN)
|
||||
global.NEW_BLOCK_REWARD1 = 1;
|
||||
NETWORK = "LOCAL";
|
||||
global.ALL_VIEW_ROWS = 1;
|
||||
global.COUNT_NODE_PROOF = 1;
|
||||
}
|
||||
else
|
||||
if(global.TEST_NETWORK)
|
||||
@ -158,12 +161,11 @@ else
|
||||
global.START_NETWORK_DATE = 1550843168000 + 1000 * 1000;
|
||||
global.START_MINING = 1000;
|
||||
global.REF_PERIOD_MINING = 1000;
|
||||
global.MIN_POWER_POW_TR = 8;
|
||||
global.MIN_POWER_POW_ACC_CREATE = 8;
|
||||
global.TRANSACTION_PROOF_COUNT = 200 * 1000;
|
||||
global.MAX_SIZE_LOG = 20 * 1024 * 1024;
|
||||
global.DELTA_BLOCK_ACCOUNT_HASH = 1000;
|
||||
global.START_BLOCK_ACCOUNT_HASH = 1000;
|
||||
global.START_BLOCK_ACCOUNT_HASH3 = 2356000;
|
||||
global.BLOCKNUM_TICKET_ALGO = 1;
|
||||
global.WALLET_NAME = "TEST";
|
||||
NETWORK = "TERA-TEST2";
|
||||
@ -172,6 +174,8 @@ else
|
||||
global.ALL_VIEW_ROWS = 1;
|
||||
global.NEW_ACCOUNT_INCREMENT = 1903000;
|
||||
global.NEW_BLOCK_REWARD1 = 1905000;
|
||||
global.COUNT_NODE_PROOF = 8;
|
||||
global.REST_START_COUNT = 10000;
|
||||
}
|
||||
if(global.LOCAL_RUN)
|
||||
{
|
||||
|
@ -24,6 +24,7 @@ module.exports = class CDB extends require("../code")
|
||||
BlockDB.OpenDBFile(FILE_NAME_HEADER, bWriteMode)
|
||||
BlockDB.OpenDBFile(FILE_NAME_BODY, bWriteMode)
|
||||
this.BlockNumDB = 0
|
||||
this.BlockNumDBMin = 0
|
||||
this.ClearBufMap()
|
||||
}
|
||||
LoadMemBlocksOnStart()
|
||||
@ -46,11 +47,17 @@ module.exports = class CDB extends require("../code")
|
||||
}
|
||||
FindStartBlockNum()
|
||||
{
|
||||
var StateTX = DApps.Accounts.DBStateTX.Read(0);
|
||||
if(StateTX)
|
||||
{
|
||||
this.BlockNumDBMin = StateTX.BlockNumMin
|
||||
}
|
||||
ToLog("BlockNumDBMin=" + this.BlockNumDBMin, 2)
|
||||
var BlockNum = this.GetMaxNumBlockDB();
|
||||
if(global.NO_CHECK_BLOCKNUM_ONSTART)
|
||||
{
|
||||
this.BlockNumDB = this.CheckBlocksOnStartFoward(BlockNum - 2, 0)
|
||||
ToLog("START_BLOCK_NUM:" + this.BlockNumDB)
|
||||
ToLog("START_BLOCK_NUM:" + this.BlockNumDB, 2)
|
||||
return ;
|
||||
}
|
||||
BlockNum = this.CheckBlocksOnStartReverse(BlockNum)
|
||||
@ -60,7 +67,7 @@ module.exports = class CDB extends require("../code")
|
||||
{
|
||||
this.TruncateBlockDB(this.BlockNumDB)
|
||||
}
|
||||
ToLog("START_BLOCK_NUM:" + this.BlockNumDB)
|
||||
ToLog("START_BLOCK_NUM:" + this.BlockNumDB, 2)
|
||||
this.CheckOnStartComplete = 1
|
||||
}
|
||||
CheckBlocksOnStartReverse(StartNum)
|
||||
@ -68,7 +75,7 @@ module.exports = class CDB extends require("../code")
|
||||
var delta = 1;
|
||||
var Count = 0;
|
||||
var PrevBlock;
|
||||
for(var num = StartNum; num >= BLOCK_PROCESSING_LENGTH; num -= delta)
|
||||
for(var num = StartNum; num >= this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2; num -= delta)
|
||||
{
|
||||
var Block = this.ReadBlockHeaderDB(num);
|
||||
if(!Block || IsZeroArr(Block.SumHash))
|
||||
@ -102,8 +109,8 @@ module.exports = class CDB extends require("../code")
|
||||
CheckBlocksOnStartFoward(StartNum, bCheckBody)
|
||||
{
|
||||
var PrevBlock;
|
||||
if(StartNum < BLOCK_PROCESSING_LENGTH2)
|
||||
StartNum = BLOCK_PROCESSING_LENGTH2
|
||||
if(StartNum < this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
StartNum = this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2
|
||||
var MaxNum = DApps.Accounts.GetHashedMaxBlockNum();
|
||||
var BlockNumTime = GetCurrentBlockNumByTime();
|
||||
if(BlockNumTime < MaxNum)
|
||||
@ -193,6 +200,7 @@ module.exports = class CDB extends require("../code")
|
||||
throw "ERROR WRITE";
|
||||
}
|
||||
this.OnWriteBlock(Block)
|
||||
if(Block.BlockNum > this.BlockNumDBMin)
|
||||
this.BlockNumDB = Block.BlockNum
|
||||
Block.bSave = true
|
||||
}
|
||||
@ -281,7 +289,7 @@ module.exports = class CDB extends require("../code")
|
||||
}
|
||||
WriteBlockHeaderDB(Block)
|
||||
{
|
||||
if(Block.BlockNum > 0)
|
||||
if(Block.BlockNum > this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
{
|
||||
if(USE_CHECK_SAVE_DB)
|
||||
if(!this.CheckSeqHashDB(Block, "WriteBlockHeaderDB"))
|
||||
@ -298,6 +306,10 @@ module.exports = class CDB extends require("../code")
|
||||
Block.SumHash = shaarr2(PrevBlock.SumHash, Block.Hash)
|
||||
Block.SumPow = PrevBlock.SumPow + GetPowPower(Block.PowHash)
|
||||
}
|
||||
else
|
||||
{
|
||||
var Stop = 1;
|
||||
}
|
||||
var BufWrite = BufLib.GetNewBuffer(BLOCK_HEADER_SIZE);
|
||||
this.BlockHeaderToBuf(BufWrite, Block)
|
||||
var Res = this.WriteBufHeaderDB(BufWrite, Block.BlockNum);
|
||||
@ -441,7 +453,7 @@ module.exports = class CDB extends require("../code")
|
||||
var Block = this.ReadBlockDB(LastBlockNum);
|
||||
if(!Block)
|
||||
{
|
||||
ToLog("************ ERROR TruncateBlockDB - not found block=" + LastBlockNum)
|
||||
ToLog("************ ERROR TruncateBlockDB - not found block=" + LastBlockNum, 2)
|
||||
return ;
|
||||
}
|
||||
this.WriteBlockDB(Block)
|
||||
@ -489,7 +501,8 @@ module.exports = class CDB extends require("../code")
|
||||
}
|
||||
ClearDataBase()
|
||||
{
|
||||
this.RewriteAllTransactions()
|
||||
if(global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
||||
global.TX_PROCESS.RunRPC("ClearDataBase", {})
|
||||
var FItem1 = BlockDB.OpenDBFile(FILE_NAME_HEADER, 1);
|
||||
FItem1.size = 0
|
||||
fs.ftruncateSync(FItem1.fd, FItem1.size)
|
||||
@ -497,9 +510,11 @@ module.exports = class CDB extends require("../code")
|
||||
FItem2.size = 0
|
||||
fs.ftruncateSync(FItem2.fd, FItem2.size)
|
||||
this.BlockNumDB = 0
|
||||
this.BlockNumDBMin = 0
|
||||
this.ClearBufMap()
|
||||
this.ClearStat()
|
||||
this.CreateGenesisBlocks()
|
||||
this.StartSyncBlockchain()
|
||||
}
|
||||
ClearBufMap()
|
||||
{
|
||||
@ -509,9 +524,12 @@ module.exports = class CDB extends require("../code")
|
||||
{
|
||||
if(TX_PROCESS.Worker)
|
||||
{
|
||||
TX_PROCESS.Worker.send({cmd:"RewriteAllTransactions"})
|
||||
if(global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
||||
{
|
||||
global.TX_PROCESS.RunRPC("RewriteAllTransactions", {})
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
BlockHeaderToBuf(BufWrite, Block)
|
||||
@ -877,57 +895,45 @@ module.exports = class CDB extends require("../code")
|
||||
if(StartNum === undefined)
|
||||
return BufLib.GetNewBuffer(10);
|
||||
var GetLength = EndBlockNum - StartNum + 1;
|
||||
var PrevBlock;
|
||||
if(StartNum > 0)
|
||||
PrevBlock = this.ReadBlockHeaderDB(StartNum - 1)
|
||||
var arr = [];
|
||||
var arr0 = this.PrevBlockChainArr;
|
||||
if(arr0 && arr0.length === GetLength)
|
||||
if(arr0 && arr0.length)
|
||||
{
|
||||
var StartNumArr = - 1;
|
||||
var EndNumArr = - 1;
|
||||
for(var i = 0; i < arr0.length; i++)
|
||||
var Block = arr0[arr0.length - 1];
|
||||
if(Block.BlockNum >= StartNum && Block.BlockNum <= EndBlockNum)
|
||||
{
|
||||
var BlockArr = arr0[i];
|
||||
if(BlockArr.BlockNum === StartNum)
|
||||
var BlockDB = this.ReadBlockHeaderDB(Block.BlockNum);
|
||||
if(!BlockDB || CompareArr(Block.SumHash, BlockDB.SumHash) !== 0)
|
||||
{
|
||||
StartNumArr = i
|
||||
arr0 = undefined
|
||||
}
|
||||
if(BlockArr.BlockNum <= EndBlockNum)
|
||||
else
|
||||
{
|
||||
EndNumArr = i
|
||||
}
|
||||
}
|
||||
if(StartNumArr >= 0 && EndNumArr > StartNumArr)
|
||||
{
|
||||
var BlockArr = arr0[EndNumArr];
|
||||
var Block = this.ReadBlockHeaderDB(BlockArr.BlockNum);
|
||||
if(Block)
|
||||
if(CompareArr(BlockArr.SumHash, Block.SumHash) == 0)
|
||||
{
|
||||
arr0.splice(EndNumArr + 1, arr.length)
|
||||
if(StartNumArr > 0)
|
||||
arr0.splice(StartNumArr - 1, StartNumArr)
|
||||
arr = arr0
|
||||
PrevBlock = Block
|
||||
StartNum = Block.BlockNum + 1
|
||||
}
|
||||
}
|
||||
}
|
||||
var i0 = 0;
|
||||
for(var num = StartNum; num <= EndBlockNum; num++)
|
||||
{
|
||||
var Block = this.ReadBlockHeaderDB(num);
|
||||
var Block = undefined;
|
||||
if(arr0)
|
||||
{
|
||||
for(var i = i0; i < arr0.length; i++)
|
||||
{
|
||||
i0 = i
|
||||
var Block0 = arr0[i];
|
||||
if(Block0.BlockNum === num)
|
||||
{
|
||||
Block = Block0
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!Block)
|
||||
Block = this.ReadBlockHeaderDB(num)
|
||||
if(!Block || !Block.Prepared || !Block.Hash)
|
||||
break;
|
||||
if(PrevBlock)
|
||||
{
|
||||
if(!PrevBlock.SumHash)
|
||||
break;
|
||||
var SumHash = shaarr2(PrevBlock.SumHash, Block.Hash);
|
||||
Block.SumHash = SumHash
|
||||
}
|
||||
arr.push(Block)
|
||||
PrevBlock = Block
|
||||
}
|
||||
this.PrevBlockChainArr = arr
|
||||
return this.ArrHeaderToBuf(WriteNum, arr);
|
||||
|
@ -209,12 +209,39 @@ function SendBlockFile(response,BlockNum,TrNum)
|
||||
{
|
||||
BlockNum = parseInt(BlockNum);
|
||||
TrNum = parseInt(TrNum);
|
||||
if(BlockNum && TrNum <= MAX_TRANSACTION_COUNT)
|
||||
if(BlockNum && BlockNum <= SERVER.GetMaxNumBlockDB() && TrNum <= MAX_TRANSACTION_COUNT)
|
||||
{
|
||||
var Block = SERVER.ReadBlockDB(BlockNum);
|
||||
if(Block && Block.arrContent)
|
||||
{
|
||||
SendToResponceFile(response, Block, TrNum);
|
||||
return ;
|
||||
}
|
||||
else
|
||||
if(!Block || !Block.TrDataPos)
|
||||
{
|
||||
LoadBlockFromNetwork({BlockNum:BlockNum}, function (Err,Block)
|
||||
{
|
||||
if(Err)
|
||||
{
|
||||
SendToResponce404(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToResponceFile(response, Block, TrNum);
|
||||
}
|
||||
});
|
||||
return ;
|
||||
}
|
||||
}
|
||||
SendToResponce404(response);
|
||||
};
|
||||
|
||||
function SendToResponceFile(response,Block,TrNum)
|
||||
{
|
||||
var Body = Block.arrContent[TrNum];
|
||||
if(Body && Body.data)
|
||||
Body = Body.data;
|
||||
if(Body && Body[0] === global.TYPE_TRANSACTION_FILE)
|
||||
{
|
||||
var TR = DApps.File.GetObjectTransaction(Body);
|
||||
@ -224,30 +251,62 @@ function SendBlockFile(response,BlockNum,TrNum)
|
||||
response.writeHead(200, {'Content-Type':TR.ContentType});
|
||||
response.end(TR.Data);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToResponce404(response);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function SendToResponce404(response)
|
||||
{
|
||||
response.writeHead(404, {'Content-Type':'text/html'});
|
||||
response.end();
|
||||
};
|
||||
HTTPCaller.DappBlockFile = function (Params)
|
||||
HTTPCaller.DappBlockFile = function (Params,response)
|
||||
{
|
||||
Params.BlockNum = ParseNum(Params.BlockNum);
|
||||
Params.TrNum = ParseNum(Params.TrNum);
|
||||
if(!Params.TrNum)
|
||||
Params.TrNum = 0;
|
||||
if(Params.BlockNum && Params.TrNum <= MAX_TRANSACTION_COUNT)
|
||||
if(Params.BlockNum && Params.BlockNum <= SERVER.GetMaxNumBlockDB() && Params.TrNum <= MAX_TRANSACTION_COUNT)
|
||||
{
|
||||
var Block = SERVER.ReadBlockDB(ParseNum(Params.BlockNum));
|
||||
var Block = SERVER.ReadBlockDB(Params.BlockNum);
|
||||
if(Block && Block.arrContent)
|
||||
{
|
||||
var Body = Block.arrContent[ParseNum(Params.TrNum)];
|
||||
SendToResponceDappFile(response, Block, Params.TrNum);
|
||||
return null;
|
||||
}
|
||||
else
|
||||
if(!Block || !Block.TrDataPos)
|
||||
{
|
||||
LoadBlockFromNetwork(Params, function (Err,Block)
|
||||
{
|
||||
if(Err)
|
||||
{
|
||||
SendToResponceResult0(response);
|
||||
}
|
||||
else
|
||||
{
|
||||
SendToResponceDappFile(response, Block, Params.TrNum);
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return {result:0};
|
||||
};
|
||||
|
||||
function SendToResponceDappFile(response,Block,TrNum)
|
||||
{
|
||||
var Result = {result:0};
|
||||
var Body = Block.arrContent[TrNum];
|
||||
if(Body)
|
||||
{
|
||||
var Type = Body[0];
|
||||
if(Type === global.TYPE_TRANSACTION_FILE)
|
||||
{
|
||||
var TR = DApps.File.GetObjectTransaction(Body);
|
||||
return {result:1, Type:Type, ContentType:TR.ContentType, Name:TR.Name, Body:TR.Data.toString('utf8')};
|
||||
Result = {result:1, Type:Type, ContentType:TR.ContentType, Name:TR.Name, Body:TR.Data.toString('utf8')};
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -256,15 +315,20 @@ HTTPCaller.DappBlockFile = function (Params)
|
||||
{
|
||||
Body = JSON.parse(App.GetScriptTransaction(Body));
|
||||
}
|
||||
return {result:1, Type:Type, Body:Body};
|
||||
Result = {result:1, Type:Type, Body:Body};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return {result:0};
|
||||
var Str = JSON.stringify(Result);
|
||||
response.end(Str);
|
||||
};
|
||||
|
||||
function SendToResponceResult0(response)
|
||||
{
|
||||
if(response)
|
||||
response.end("{\"result\":0}");
|
||||
};
|
||||
var glBlock0;
|
||||
HTTPCaller.DappStaticCall = function (Params)
|
||||
HTTPCaller.DappStaticCall = function (Params,response)
|
||||
{
|
||||
DApps.Accounts.BeginBlock();
|
||||
DApps.Accounts.BeginTransaction();
|
||||
@ -285,7 +349,13 @@ HTTPCaller.DappStaticCall = function (Params)
|
||||
{
|
||||
return {result:0, RetValue:"" + e};
|
||||
}
|
||||
return {result:1, RetValue:RetValue};
|
||||
var Str = JSON.stringify({result:1, RetValue:RetValue});
|
||||
if(Str.length > 16000)
|
||||
{
|
||||
return {result:0, RetValue:"Error result length (more 16000)"};
|
||||
}
|
||||
response.end(Str);
|
||||
return null;
|
||||
};
|
||||
HTTPCaller.DappInfo = function (Params,responce,ObjectOnly)
|
||||
{
|
||||
@ -307,6 +377,8 @@ HTTPCaller.DappInfo = function (Params,responce,ObjectOnly)
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
if(!Account)
|
||||
Account = {};
|
||||
Account.SmartState = {};
|
||||
}
|
||||
}
|
||||
@ -1391,7 +1463,7 @@ function GetFileSimple(Path)
|
||||
|
||||
function SaveFileSimple(Path,Str)
|
||||
{
|
||||
global.SendHTMLMap[Path] = undefined;
|
||||
global.SendHTMLMap = {};
|
||||
var Key = "GetFileSimple-" + Path;
|
||||
global.SendHTMLMap[Key] = Str;
|
||||
SaveToFile(Path, Str);
|
||||
|
@ -73,6 +73,12 @@ require("./log.js");
|
||||
global.BufLib = require("../core/buffer");
|
||||
require('../HTML/JS/sha3.js');
|
||||
require('../HTML/JS/coinlib.js');
|
||||
global.GetCurrentBlockNumByTime = function GetCurrentBlockNumByTime()
|
||||
{
|
||||
var CurTimeNum = GetCurrentTime() - FIRST_TIME_BLOCK;
|
||||
var StartBlockNum = Math.trunc((CurTimeNum + CONSENSUS_PERIOD_TIME) / CONSENSUS_PERIOD_TIME);
|
||||
return StartBlockNum;
|
||||
};
|
||||
global.DelDir = function (Path)
|
||||
{
|
||||
if(Path.substr(Path.length - 1, 1) === "/")
|
||||
|
@ -15,89 +15,93 @@ var file_name_info = GetDataPath("info.log"), file_name_infoPrev = GetDataPath("
|
||||
CheckSizeLogFile(file_name_info, file_name_infoPrev);
|
||||
var file_name_log = GetDataPath("log.log"), file_name_logPrev = GetDataPath("log-prev.log");
|
||||
CheckSizeLogFile(file_name_log, file_name_logPrev);
|
||||
var file_name_log_web = GetDataPath("web.log"), file_name_log_webPrev = GetDataPath("web-prev.log");
|
||||
CheckSizeLogFile(file_name_log_web, file_name_log_webPrev);
|
||||
var StartStatTime, file_name_error = GetDataPath("err.log"), file_name_errorPrev = GetDataPath("err-prev.log");
|
||||
|
||||
function ToLogFile(t,e,r)
|
||||
function ToLogFile(e,t,r)
|
||||
{
|
||||
e instanceof Error && (e = e.message + "\n" + e.stack), global.START_SERVER || (e = global.PROCESS_NAME + ": " + e), "MAIN" !== global.PROCESS_NAME && process.send ? process.send({cmd:"log",
|
||||
message:e}) : (console.log(START_PORT_NUMBER + ": " + GetStrOnlyTime() + ": " + e), r || SaveToLogFileSync(t, e));
|
||||
t instanceof Error && (t = t.message + "\n" + t.stack), global.START_SERVER || (t = global.PROCESS_NAME + ": " + t), "MAIN" !== global.PROCESS_NAME && process.send ? process.send({cmd:"log",
|
||||
message:t}) : (console.log(START_PORT_NUMBER + ": " + GetStrOnlyTime() + ": " + t), r || SaveToLogFileSync(e, t));
|
||||
};
|
||||
|
||||
function ToLogClient(t,e,r)
|
||||
function ToLogClient(e,t,r)
|
||||
{
|
||||
t && (ToLogFile(file_name_log, t), e || (e = ""), ArrLogClient.push({text:GetStrOnlyTime() + " " + t, key:e, final:r}), 13 < ArrLogClient.length && ArrLogClient.shift());
|
||||
e && (ToLogFile(file_name_log, e), t || (t = ""), ArrLogClient.push({text:GetStrOnlyTime() + " " + e, key:t, final:r}), 13 < ArrLogClient.length && ArrLogClient.shift());
|
||||
};
|
||||
CheckSizeLogFile(file_name_error, file_name_errorPrev), global.ToLog = function (t,e)
|
||||
CheckSizeLogFile(file_name_error, file_name_errorPrev), global.ToLog = function (e,t)
|
||||
{
|
||||
void 0 === e && (e = 1), e && e > global.LOG_LEVEL || (global.ALL_LOG_TO_CLIENT ? ToLogClient(t, void 0, void 0) : ToLogFile(file_name_log,
|
||||
t));
|
||||
}, global.SmallAddr = function (t)
|
||||
void 0 === t && (t = 1), t && t > global.LOG_LEVEL || (global.ALL_LOG_TO_CLIENT ? ToLogClient(e, void 0, void 0) : ToLogFile(file_name_log,
|
||||
e));
|
||||
}, global.ToLogWeb = function (e)
|
||||
{
|
||||
return t.substr(0, 5);
|
||||
}, global.ToErrorTrace = function (t)
|
||||
}, global.SmallAddr = function (e)
|
||||
{
|
||||
ToError(t + ":" + (new Error).stack);
|
||||
}, global.ToLogTrace = function (t)
|
||||
return e.substr(0, 5);
|
||||
}, global.ToErrorTrace = function (e)
|
||||
{
|
||||
ToErrorTrace(t);
|
||||
}, global.ToInfo = function (t)
|
||||
ToError(e + ":" + (new Error).stack);
|
||||
}, global.ToLogTrace = function (e)
|
||||
{
|
||||
ToLogFile(file_name_info, t, 1);
|
||||
}, global.ToError = function (t)
|
||||
ToErrorTrace(e);
|
||||
}, global.ToInfo = function (e)
|
||||
{
|
||||
ToLogFile(file_name_error, t);
|
||||
ToLogFile(file_name_info, e, 1);
|
||||
}, global.ToError = function (e)
|
||||
{
|
||||
ToLogFile(file_name_error, e);
|
||||
}, global.ArrLogClient = [], global.ToLogClient = ToLogClient, global.ToLogClient0 = ToLogClient;
|
||||
var CONTEXT_STATS = {Total:{}, Interval:[]}, CONTEXT_ERRORS = {Total:{}, Interval:[]}, CurStatIndex = 0;
|
||||
|
||||
function GetCurrentStatIndex()
|
||||
{
|
||||
var t = 2 * MAX_STAT_PERIOD + 2;
|
||||
return CurStatIndex % t;
|
||||
var e = 2 * MAX_STAT_PERIOD + 2;
|
||||
return CurStatIndex % e;
|
||||
};
|
||||
|
||||
function ResizeArrMax(t)
|
||||
function ResizeArrMax(e)
|
||||
{
|
||||
for(var e = [], r = Math.trunc(t.length / 2), o = 0; o < r; o++)
|
||||
e[o] = Math.max(t[2 * o], t[2 * o + 1]);
|
||||
return e;
|
||||
for(var t = [], r = Math.trunc(e.length / 2), o = 0; o < r; o++)
|
||||
t[o] = Math.max(e[2 * o], e[2 * o + 1]);
|
||||
return t;
|
||||
};
|
||||
|
||||
function ResizeArrAvg(t)
|
||||
function ResizeArrAvg(e)
|
||||
{
|
||||
for(var e = [], r = Math.trunc(t.length / 2), o = 0; o < r; o++)
|
||||
e[o] = (t[2 * o] + t[2 * o + 1]) / 2;
|
||||
return e;
|
||||
for(var t = [], r = Math.trunc(e.length / 2), o = 0; o < r; o++)
|
||||
t[o] = (e[2 * o] + e[2 * o + 1]) / 2;
|
||||
return t;
|
||||
};
|
||||
|
||||
function ResizeArr(t)
|
||||
function ResizeArr(e)
|
||||
{
|
||||
for(var e = [], r = Math.trunc(t.length / 2), o = 0; o < r; o++)
|
||||
e[o] = t[2 * o];
|
||||
return e;
|
||||
for(var t = [], r = Math.trunc(e.length / 2), o = 0; o < r; o++)
|
||||
t[o] = e[2 * o];
|
||||
return t;
|
||||
};
|
||||
|
||||
function GetDiagramData(t,e)
|
||||
function GetDiagramData(e,t)
|
||||
{
|
||||
var r, o = 2 * MAX_STAT_PERIOD + 2;
|
||||
r = "MAX:" === e.substr(0, 4);
|
||||
for(var n, a = MAX_STAT_PERIOD, l = (GetCurrentStatIndex() - a + o) % o, i = (t.Total, []), T = void 0, g = l; g < l + a; g++)
|
||||
r = "MAX:" === t.substr(0, 4);
|
||||
for(var n, a = MAX_STAT_PERIOD, l = (GetCurrentStatIndex() - a + o) % o, i = (e.Total, []), T = void 0, g = l; g < l + a; g++)
|
||||
{
|
||||
var S = g % o;
|
||||
if(n = t.Interval[S])
|
||||
if(n = e.Interval[S])
|
||||
{
|
||||
var f = n[e];
|
||||
void 0 !== f ? r ? i.push(f) : (void 0 !== T ? i.push(f - T) : i.push(f), T = f) : i.push(0);
|
||||
var _ = n[t];
|
||||
void 0 !== _ ? r ? i.push(_) : (void 0 !== T ? i.push(_ - T) : i.push(_), T = _) : i.push(0);
|
||||
}
|
||||
}
|
||||
return i;
|
||||
};
|
||||
|
||||
function CalcInterval(t,e,r)
|
||||
function CalcInterval(e,t,r)
|
||||
{
|
||||
for(var o, n = 2 * MAX_STAT_PERIOD + 2, a = {}, l = (e - r + n) % n, i = t.Total, T = l; T < l + r; T++)
|
||||
for(var o, n = 2 * MAX_STAT_PERIOD + 2, a = {}, l = (t - r + n) % n, i = e.Total, T = l; T < l + r; T++)
|
||||
{
|
||||
var g = T % n;
|
||||
if(o = t.Interval[g])
|
||||
if(o = e.Interval[g])
|
||||
break;
|
||||
}
|
||||
if(o)
|
||||
@ -106,95 +110,98 @@ function CalcInterval(t,e,r)
|
||||
return a;
|
||||
};
|
||||
|
||||
function AddToStatContext(t,e,r)
|
||||
function AddToStatContext(e,t,r)
|
||||
{
|
||||
void 0 === r && (r = 1);
|
||||
var o = t.Total[e];
|
||||
o || (o = 0), "MAX:" === e.substr(0, 4) ? o = Math.max(o, r) : o += r, t.Total[e] = o, StartStatTime || (StartStatTime = GetCurrentTime(0));
|
||||
var o = e.Total[t];
|
||||
o || (o = 0), "MAX:" === t.substr(0, 4) ? o = Math.max(o, r) : o += r, e.Total[t] = o, StartStatTime || (StartStatTime = GetCurrentTime(0));
|
||||
};
|
||||
|
||||
function CopyStatInterval(t,e)
|
||||
function CopyStatInterval(e,t)
|
||||
{
|
||||
var r = t.Interval[e];
|
||||
r || (r = {}, t.Interval[e] = r);
|
||||
var o = t.Total;
|
||||
var r = e.Interval[t];
|
||||
r || (r = {}, e.Interval[t] = r);
|
||||
var o = e.Total;
|
||||
for(var n in o)
|
||||
r[n] = o[n], "MAX:" === n.substr(0, 4) && (o[n] = 0);
|
||||
};
|
||||
|
||||
function SaveToLogFileAsync(t,o)
|
||||
function SaveToLogFileAsync(e,o)
|
||||
{
|
||||
fs.open(t, "a", void 0, function (t,r)
|
||||
fs.open(e, "a", void 0, function (e,r)
|
||||
{
|
||||
if(t)
|
||||
if(e)
|
||||
console.log("Ошибка открытия лог-файла ошибок");
|
||||
else
|
||||
{
|
||||
var e = GetStrTime() + " : " + o + "\r\n";
|
||||
fs.write(r, e, null, "utf8", function (t,e)
|
||||
var t = GetStrTime() + " : " + o + "\r\n";
|
||||
fs.write(r, t, null, "utf8", function (e,t)
|
||||
{
|
||||
t ? console.log("Ошибка записи в лог-файл ошибок!") : (console.log(o), fs.close(r));
|
||||
e ? console.log("Ошибка записи в лог-файл ошибок!") : fs.close(r, function (e)
|
||||
{
|
||||
e && console.log(e);
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
function SaveToLogFileSync(t,e)
|
||||
function SaveToLogFileSync(e,t)
|
||||
{
|
||||
try
|
||||
{
|
||||
var r = GetStrTime() + " : " + e + "\r\n", o = fs.openSync(t, "a");
|
||||
var r = GetStrTime() + " : " + t + "\r\n", o = fs.openSync(e, "a");
|
||||
fs.writeSync(o, r, null, "utf8"), fs.closeSync(o);
|
||||
}
|
||||
catch(t)
|
||||
catch(e)
|
||||
{
|
||||
console.log(t.message);
|
||||
console.log(e.message);
|
||||
}
|
||||
};
|
||||
global.PrepareStatEverySecond = function ()
|
||||
{
|
||||
CurStatIndex++;
|
||||
var t = GetCurrentStatIndex();
|
||||
CopyStatInterval(CONTEXT_STATS, t), CopyStatInterval(CONTEXT_ERRORS, t);
|
||||
}, global.TO_ERROR_LOG = function (t,e,r,o,n,a)
|
||||
var e = GetCurrentStatIndex();
|
||||
CopyStatInterval(CONTEXT_STATS, e), CopyStatInterval(CONTEXT_ERRORS, e);
|
||||
}, global.TO_ERROR_LOG = function (e,t,r,o,n,a)
|
||||
{
|
||||
r instanceof Error && (r = r.message + "\n"), "rinfo" === o ? r += " from: " + n.address + ":" + n.port : "node" === o && (r += " from: " + n.ip + ":" + n.port);
|
||||
var l = t + ":" + e;
|
||||
var l = e + ":" + t;
|
||||
ToError(" ==ERROR== " + l + " " + r), AddToStatContext(CONTEXT_ERRORS, l), ADD_TO_STAT("ERRORS");
|
||||
}, global.HASH_RATE = 0, global.ADD_HASH_RATE = function (t)
|
||||
}, global.HASH_RATE = 0, global.ADD_HASH_RATE = function (e)
|
||||
{
|
||||
t /= 1e6, global.HASH_RATE += t, ADD_TO_STAT("HASHRATE", t);
|
||||
}, global.GET_STAT = function (t)
|
||||
e /= 1e6, global.HASH_RATE += e, ADD_TO_STAT("HASHRATE", e);
|
||||
}, global.GET_STAT = function (e)
|
||||
{
|
||||
var e = CONTEXT_STATS.Total[t];
|
||||
return e || (e = 0), e;
|
||||
}, global.ADD_TO_STAT_TIME = function (t,e,r)
|
||||
var t = CONTEXT_STATS.Total[e];
|
||||
return t || (t = 0), t;
|
||||
}, global.ADD_TO_STAT_TIME = function (e,t,r)
|
||||
{
|
||||
if(global.STAT_MODE)
|
||||
{
|
||||
if(r && 2 !== global.STAT_MODE)
|
||||
return ;
|
||||
var o = process.hrtime(e), n = 1e3 * o[0] + o[1] / 1e6;
|
||||
ADD_TO_STAT(t, n);
|
||||
var o = process.hrtime(t), n = 1e3 * o[0] + o[1] / 1e6;
|
||||
ADD_TO_STAT(e, n);
|
||||
}
|
||||
}, global.ADD_TO_STAT = function (t,e,r)
|
||||
}, global.ADD_TO_STAT = function (e,t,r)
|
||||
{
|
||||
if(global.STAT_MODE)
|
||||
{
|
||||
if(r && 2 !== global.STAT_MODE)
|
||||
return ;
|
||||
AddToStatContext(CONTEXT_STATS, t, e);
|
||||
AddToStatContext(CONTEXT_STATS, e, t);
|
||||
}
|
||||
}, global.GET_STATDIAGRAMS = function (t)
|
||||
}, global.GET_STATDIAGRAMS = function (e)
|
||||
{
|
||||
GetCurrentTime();
|
||||
var e = GetCurrentStatIndex();
|
||||
if(!t || !t.length)
|
||||
var t = GetCurrentStatIndex();
|
||||
if(!e || !e.length)
|
||||
return [];
|
||||
for(var r = [], o = 0; o < t.length; o++)
|
||||
for(var r = [], o = 0; o < e.length; o++)
|
||||
{
|
||||
var n = t[o], a = GetDiagramData(CONTEXT_STATS, n);
|
||||
r.push({name:n, maxindex:e, arr:a, starttime:StartStatTime - 0, steptime:1});
|
||||
var n = e[o], a = GetDiagramData(CONTEXT_STATS, n);
|
||||
r.push({name:n, maxindex:t, arr:a, starttime:StartStatTime - 0, steptime:1});
|
||||
}
|
||||
var l = void 0;
|
||||
for(o = 0; o < r.length; o++)
|
||||
@ -209,48 +216,48 @@ global.PrepareStatEverySecond = function ()
|
||||
for(var g = 0, S = 0; S < T.length; S++)
|
||||
T[S] && (g += T[S]);
|
||||
0 < T.length && (g /= T.length);
|
||||
var f = 1;
|
||||
var _ = 1;
|
||||
if("MAX:" === i.name.substr(0, 4))
|
||||
for(; 500 <= T.length; )
|
||||
T = ResizeArrMax(T), f *= 2;
|
||||
T = ResizeArrMax(T), _ *= 2;
|
||||
else
|
||||
for(; 500 <= T.length; )
|
||||
T = ResizeArrAvg(T), f *= 2;
|
||||
i.AvgValue = g, i.steptime = f, i.arr = T.slice(1);
|
||||
T = ResizeArrAvg(T), _ *= 2;
|
||||
i.AvgValue = g, i.steptime = _, i.arr = T.slice(1);
|
||||
}
|
||||
return r;
|
||||
}, global.GET_STATS = function (t)
|
||||
}, global.GET_STATS = function (e)
|
||||
{
|
||||
var e = GetCurrentTime(), r = GetCurrentStatIndex();
|
||||
var t = GetCurrentTime(), r = GetCurrentStatIndex();
|
||||
return {stats:{Counter:CONTEXT_STATS.Total, Counter10S:CalcInterval(CONTEXT_STATS, r, 10), Counter10M:CalcInterval(CONTEXT_STATS,
|
||||
r, 600)}, errors:{Counter:CONTEXT_ERRORS.Total, Counter10S:CalcInterval(CONTEXT_ERRORS, r, 10), Counter10M:CalcInterval(CONTEXT_ERRORS,
|
||||
r, 600)}, period:(e - StartStatTime) / 1e3, Confirmation:[]};
|
||||
r, 600)}, period:(t - StartStatTime) / 1e3, Confirmation:[]};
|
||||
}, global.StartCommonStat = function ()
|
||||
{
|
||||
for(var t in CONTEXT_STATS.Total)
|
||||
for(var e in CONTEXT_STATS.Total)
|
||||
return ;
|
||||
ClearCommonStat();
|
||||
}, global.ClearCommonStat = function ()
|
||||
{
|
||||
StartStatTime = void (CurStatIndex = 0), CONTEXT_STATS = {Total:{}, Interval:[]}, CONTEXT_ERRORS = {Total:{}, Interval:[]},
|
||||
global.HASH_RATE = 0, SERVER.ClearStat();
|
||||
}, global.ResizeArrAvg = ResizeArrAvg, global.ResizeArrMax = ResizeArrMax, DEBUG_MODE ? global.TO_DEBUG_LOG = function (t,e,r,o)
|
||||
}, global.ResizeArrAvg = ResizeArrAvg, global.ResizeArrMax = ResizeArrMax, DEBUG_MODE ? global.TO_DEBUG_LOG = function (e,t,r,o)
|
||||
{
|
||||
DEBUG_MODE && ("rinfo" === e && (t += " from: " + r.address + ":" + r.port + " - " + o.length), ToLog(t));
|
||||
} : global.TO_DEBUG_LOG = function (t,e,r,o)
|
||||
DEBUG_MODE && ("rinfo" === t && (e += " from: " + r.address + ":" + r.port + " - " + o.length), ToLog(e));
|
||||
} : global.TO_DEBUG_LOG = function (e,t,r,o)
|
||||
{
|
||||
}, global.GetStrOnlyTime = function (t)
|
||||
}, global.GetStrOnlyTime = function (e)
|
||||
{
|
||||
if(!global.GetCurrentTime)
|
||||
return ":::";
|
||||
t || (t = GetCurrentTime());
|
||||
var e = "" + t.getHours().toStringZ(2);
|
||||
return e = (e = (e = e + ":" + t.getMinutes().toStringZ(2)) + ":" + t.getSeconds().toStringZ(2)) + "." + t.getMilliseconds().toStringZ(3);
|
||||
}, global.GetStrTime = function (t)
|
||||
e || (e = GetCurrentTime());
|
||||
var t = "" + e.getHours().toStringZ(2);
|
||||
return t = (t = (t = t + ":" + e.getMinutes().toStringZ(2)) + ":" + e.getSeconds().toStringZ(2)) + "." + e.getMilliseconds().toStringZ(3);
|
||||
}, global.GetStrTime = function (e)
|
||||
{
|
||||
if(!global.GetCurrentTime)
|
||||
return ":::";
|
||||
t || (t = GetCurrentTime());
|
||||
var e = "" + t.getDate().toStringZ(2);
|
||||
return e = (e = (e = (e = (e = (e = e + "." + (1 + t.getMonth()).toStringZ(2)) + "." + t.getFullYear()) + " " + t.getHours().toStringZ(2)) + ":" + t.getMinutes().toStringZ(2)) + ":" + t.getSeconds().toStringZ(2)) + "." + t.getMilliseconds().toStringZ(3);
|
||||
e || (e = GetCurrentTime());
|
||||
var t = "" + e.getDate().toStringZ(2);
|
||||
return t = (t = (t = (t = (t = (t = t + "." + (1 + e.getMonth()).toStringZ(2)) + "." + e.getFullYear()) + " " + e.getHours().toStringZ(2)) + ":" + e.getMinutes().toStringZ(2)) + ":" + e.getSeconds().toStringZ(2)) + "." + e.getMilliseconds().toStringZ(3);
|
||||
};
|
||||
|
442
Source/core/rest-loader.js
Normal file
442
Source/core/rest-loader.js
Normal file
@ -0,0 +1,442 @@
|
||||
/*
|
||||
* @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";
|
||||
module.exports = class CRest extends require("./db/block-db")
|
||||
{
|
||||
constructor(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
||||
{
|
||||
super(SetKeyPair, RunIP, RunPort, UseRNDHeader, bVirtual)
|
||||
}
|
||||
CheckSyncRest()
|
||||
{
|
||||
var BlockNumTime = GetCurrentBlockNumByTime();
|
||||
var Delta = BlockNumTime - this.BlockNumDB;
|
||||
if(Delta > REST_START_COUNT + DELTA_BLOCK_ACCOUNT_HASH + 500)
|
||||
{
|
||||
var BlockNumRest = GetCurrentRestNum(REST_START_COUNT + DELTA_BLOCK_ACCOUNT_HASH + 500);
|
||||
if(this.BlockNumDB >= this.BlockNumDBMin && this.BlockNumDB <= this.BlockNumDBMin + BLOCK_PROCESSING_LENGTH2)
|
||||
{
|
||||
}
|
||||
else
|
||||
if(BlockNumRest > this.BlockNumDB)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LoadRestContext = undefined
|
||||
return ;
|
||||
}
|
||||
this.LoadRestContext = {Mode:0, BlockNum:BlockNumRest, BlockNumRest:BlockNumRest, WasDelta:Delta, BlockNumProof:BlockNumRest + DELTA_BLOCK_ACCOUNT_HASH,
|
||||
CountProof:COUNT_BLOCKS_FOR_LOAD, StartTimeHistory:Date.now(), MaxTimeOut:600 * 1000, LoopSyncRest:1, SendGetHeaderCount:0,
|
||||
ReceiveHeaderCount:0, ArrProof:[], MapSend:{}}
|
||||
for(var i = 0; i < this.NodesArr.length; i++)
|
||||
{
|
||||
this.NodesArr[i].SendRestGetHeader = 0
|
||||
}
|
||||
ToLog("**********START REST MODE: " + this.LoadRestContext.BlockNumProof)
|
||||
}
|
||||
else
|
||||
{
|
||||
this.LoadRestContext = undefined
|
||||
}
|
||||
}
|
||||
LoopSyncRest()
|
||||
{
|
||||
let Context = this.LoadRestContext;
|
||||
var DeltaTime = Date.now() - Context.StartTimeHistory;
|
||||
switch(Context.Mode)
|
||||
{
|
||||
case 0:
|
||||
var ArrNodes = this.GetActualNodes();
|
||||
for(var i = 0; i < ArrNodes.length; i++)
|
||||
{
|
||||
var Node = ArrNodes[i];
|
||||
if(!Node || Node.SendRestGetHeader)
|
||||
continue;
|
||||
Node.SendRestGetHeader = 1
|
||||
ToLog("Send rest get headers from " + Context.BlockNumProof + " to " + NodeName(Node), 2)
|
||||
this.SendF(Node, {"Method":"GETBLOCKHEADER", "Data":{Foward:1, BlockNum:Context.BlockNumProof, Hash:[]}, "Context":{F:this.RETBLOCKHEADER_REST.bind(this)},
|
||||
})
|
||||
Context.SendGetHeaderCount++
|
||||
if(Context.SendGetHeaderCount >= COUNT_NODE_PROOF * 2)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode + " Send:" + Context.SendGetHeaderCount, 2)
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
if(DeltaTime > 5000 || Context.ReceiveHeaderCount === Context.SendGetHeaderCount)
|
||||
{
|
||||
if(Context.ReceiveHeaderCount >= COUNT_NODE_PROOF)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode + " Receive:" + Context.ReceiveHeaderCount + "/" + Context.SendGetHeaderCount, 2)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
var MapSumPower = {};
|
||||
for(var i = 0; i < Context.ArrProof.length; i++)
|
||||
{
|
||||
var Item = Context.ArrProof[i];
|
||||
if(!MapSumPower[Item.SumPower])
|
||||
MapSumPower[Item.SumPower] = 0
|
||||
MapSumPower[Item.SumPower]++
|
||||
}
|
||||
var MaxCount = 0, MaxPow = 0;
|
||||
for(var key in MapSumPower)
|
||||
{
|
||||
if(MapSumPower[key] >= MaxCount)
|
||||
{
|
||||
MaxCount = MapSumPower[key]
|
||||
MaxPow = parseInt(key)
|
||||
}
|
||||
}
|
||||
if(MaxCount < 2 || MaxPow === 0)
|
||||
{
|
||||
ToLog("****************************************************************** Error MaxPow - reload.")
|
||||
this.CheckSyncRest()
|
||||
return ;
|
||||
}
|
||||
for(var i = 0; i < Context.ArrProof.length; i++)
|
||||
{
|
||||
var Item = Context.ArrProof[i];
|
||||
if(Item.SumPower !== MaxPow)
|
||||
{
|
||||
var Str = "BAD SumPower: " + Item.SumPower + "/" + MaxPow;
|
||||
ToLog(Str + " from: " + NodeName(Item.Node), 2)
|
||||
}
|
||||
else
|
||||
if(Item.SumPower && Item.arr.length >= Context.CountProof)
|
||||
{
|
||||
Item.OK = 1
|
||||
Context.BlockProof = Item.arr[0]
|
||||
}
|
||||
}
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode + " SumPower:" + MaxPow, 2)
|
||||
break;
|
||||
case 3:
|
||||
if(global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
var Block = {BlockNum:Context.BlockNumRest};
|
||||
this.BlockNumDB = Block.BlockNum
|
||||
this.BlockNumDBMin = Block.BlockNum
|
||||
this.WriteBlockHeaderDB(Block)
|
||||
this.UseTruncateBlockDB = undefined
|
||||
global.TX_PROCESS.RunRPC("TXPrepareLoadRest", Block.BlockNum, function (Err,Params)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
})
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
break;
|
||||
case 5:
|
||||
let BlockProof = Context.BlockProof;
|
||||
var SendCount = 0;
|
||||
if(BlockProof)
|
||||
for(var i = 0; i < Context.ArrProof.length; i++)
|
||||
{
|
||||
let Item = Context.ArrProof[i];
|
||||
if(Item.OK)
|
||||
{
|
||||
SendCount++
|
||||
ToLog("Send rest get block proof:" + BlockProof.BlockNum + " to " + NodeName(Item.Node), 2)
|
||||
this.SendF(Item.Node, {"Method":"GETBLOCK", "Data":{BlockNum:BlockProof.BlockNum, TreeHash:BlockProof.TreeHash}, "Context":{F:function (Info)
|
||||
{
|
||||
if(Context.TxProof)
|
||||
return ;
|
||||
var Data = BufLib.GetObjectFromBuffer(Info.Data, FORMAT_BLOCK_TRANSFER, WRK_BLOCK_TRANSFER);
|
||||
Info.Data = undefined
|
||||
if(Data.BlockNum !== BlockProof.BlockNum || CompareArr(Data.TreeHash, BlockProof.TreeHash) !== 0)
|
||||
{
|
||||
ToLog("Error get proof block from " + NodeName(Item.Node), 2)
|
||||
return ;
|
||||
}
|
||||
var TreeHash = CalcTreeHashFromArrBody(Data.BlockNum, Data.arrContent);
|
||||
if(CompareArr(BlockProof.TreeHash, TreeHash) !== 0)
|
||||
{
|
||||
ToLog("Error TreeHash in proof block from " + NodeName(Item.Node), 2)
|
||||
return ;
|
||||
}
|
||||
ToLog("GET BLOCK proof from " + NodeName(Item.Node), 2)
|
||||
var FindTx = undefined;
|
||||
for(var n = 0; n < Data.arrContent.length; n++)
|
||||
{
|
||||
var Body = Data.arrContent[n];
|
||||
if(Body[0] === TYPE_TRANSACTION_ACC_HASH)
|
||||
{
|
||||
try
|
||||
{
|
||||
FindTx = BufLib.GetObjectFromBuffer(Body, FORMAT_ACCOUNT_HASH3, {})
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
ToLog("Error parsing Body[" + n + "] block proof: " + e, 2)
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!FindTx)
|
||||
return ;
|
||||
Context.TxProof = FindTx
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
Context.AccTaskList = []
|
||||
Context.AccTaskFinished = 0
|
||||
var AccCount = FindTx.AccountMax + 1;
|
||||
for(var n = 0; n < AccCount; n += MAX_ACCOUNTS_TRANSFER)
|
||||
{
|
||||
var Task = {StartNum:n, Count:MAX_ACCOUNTS_TRANSFER, Time:0, MapSend:{}};
|
||||
if(Task.StartNum + Task.Count > AccCount)
|
||||
Task.Count = AccCount - Task.StartNum
|
||||
Context.AccTaskList.push(Task)
|
||||
}
|
||||
Context.SmartTaskList = []
|
||||
Context.SmartTaskFinished = 0
|
||||
for(var n = 0; n < FindTx.SmartCount; n += MAX_SMARTS_TRANSFER)
|
||||
{
|
||||
var Task = {StartNum:n, Count:MAX_SMARTS_TRANSFER, Time:0, MapSend:{}};
|
||||
if(Task.StartNum + Task.Count > FindTx.SmartCount)
|
||||
Task.Count = FindTx.SmartCount - Task.StartNum
|
||||
Context.SmartTaskList.push(Task)
|
||||
}
|
||||
}}, })
|
||||
if(SendCount >= 5)
|
||||
break;
|
||||
}
|
||||
}
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
break;
|
||||
case 6:
|
||||
break;
|
||||
case 7:
|
||||
if(Context.AccTaskFinished === Context.AccTaskList.length)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
break;
|
||||
}
|
||||
var CurTime = Date.now();
|
||||
for(var i = 0; i < Context.AccTaskList.length; i++)
|
||||
{
|
||||
let Task = Context.AccTaskList[i];
|
||||
var Delta = CurTime - Task.Time;
|
||||
if(Delta > 3 * 1000 && !Task.OK)
|
||||
{
|
||||
var Ret = this.GetNextNode(Task, "", 1);
|
||||
if(Ret.Result)
|
||||
{
|
||||
ToLog("Send GETREST Num:" + Task.StartNum + "-" + Task.Count + " to " + NodeName(Ret.Node), 2)
|
||||
var SELF = this;
|
||||
this.SendF(Ret.Node, {"Method":"GETREST", "Data":{BlockNum:Context.BlockNumRest, AccNum:Task.StartNum, Count:Task.Count}, "Context":{F:function (Info)
|
||||
{
|
||||
if(Task.OK)
|
||||
return ;
|
||||
var Data = SELF.DataFromF(Info);
|
||||
if(!Data.Result)
|
||||
return ;
|
||||
ToLog("Result GETREST Num:" + Task.StartNum + " arr=" + Data.Arr.length + " from " + NodeName(Info.Node), 2)
|
||||
if(!global.TX_PROCESS || !global.TX_PROCESS.RunRPC)
|
||||
return ;
|
||||
global.TX_PROCESS.RunRPC("TXWriteAccArr", {StartNum:Task.StartNum, Arr:Data.Arr}, function (Err,Params)
|
||||
{
|
||||
Task.OK = 1
|
||||
Context.AccTaskFinished++
|
||||
})
|
||||
}}, })
|
||||
Task.Time = CurTime
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if(Context.SmartTaskFinished === Context.SmartTaskList.length)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
break;
|
||||
}
|
||||
var CurTime = Date.now();
|
||||
for(var i = 0; i < Context.SmartTaskList.length; i++)
|
||||
{
|
||||
let Task = Context.SmartTaskList[i];
|
||||
var Delta = CurTime - Task.Time;
|
||||
if(Delta > 3 * 1000 && !Task.OK)
|
||||
{
|
||||
var Ret = this.GetNextNode(Task, "", 1);
|
||||
if(Ret.Result)
|
||||
{
|
||||
ToLog("Send GETSMART Num:" + Task.StartNum + "-" + Task.Count + " to " + NodeName(Ret.Node), 2)
|
||||
var SELF = this;
|
||||
this.SendF(Ret.Node, {"Method":"GETSMART", "Data":{BlockNum:Context.BlockNumRest, SmartNum:Task.StartNum, Count:Task.Count},
|
||||
"Context":{F:function (Info)
|
||||
{
|
||||
if(Task.OK)
|
||||
return ;
|
||||
var Data = SELF.DataFromF(Info);
|
||||
if(!Data.Result)
|
||||
return ;
|
||||
ToLog("Result GETSMART Num:" + Task.StartNum + " arr=" + Data.Arr.length + " from " + NodeName(Info.Node), 2)
|
||||
Task.Node = Info.Node
|
||||
if(!global.TX_PROCESS || !global.TX_PROCESS.RunRPC)
|
||||
return ;
|
||||
global.TX_PROCESS.RunRPC("TXWriteSmartArr", {StartNum:Task.StartNum, Arr:Data.Arr}, function (Err,Params)
|
||||
{
|
||||
Task.OK = 1
|
||||
Context.SmartTaskFinished++
|
||||
})
|
||||
}}, })
|
||||
Task.Time = CurTime
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if(!global.TX_PROCESS || !global.TX_PROCESS.RunRPC)
|
||||
return ;
|
||||
var ErrSmartNum = CheckHashSmarts(Context.TxProof.SmartHash);
|
||||
if(ErrSmartNum > 0)
|
||||
{
|
||||
var Str = "Error hash in smart num: " + ErrSmartNum;
|
||||
ToLog(Str, 2)
|
||||
var t = Math.trunc(ErrSmartNum / MAX_SMARTS_TRANSFER);
|
||||
var Task = Context.SmartTaskList[t];
|
||||
if(!Task)
|
||||
{
|
||||
ToLog("error task number: " + t)
|
||||
Context.Mode = 100
|
||||
}
|
||||
else
|
||||
{
|
||||
Task.OK = 0
|
||||
Context.Mode--
|
||||
Context.SmartTaskFinished--
|
||||
this.AddToBan(Task.Node, Str)
|
||||
}
|
||||
break;
|
||||
}
|
||||
global.TX_PROCESS.RunRPC("TXWriteAccHash", {}, function (Err,Params)
|
||||
{
|
||||
if(!Params)
|
||||
return ;
|
||||
if(CompareArr(Context.TxProof.AccHash, Params.AccHash) === 0 && CompareArr(Context.TxProof.SmartHash, Params.SmartHash) === 0)
|
||||
{
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
}
|
||||
else
|
||||
{
|
||||
ToLog("ERROR RESTS LOAD:")
|
||||
ToLog("Must AccHash:" + GetHexFromArr(Context.TxProof.AccHash))
|
||||
ToLog("Must SmartHash:" + GetHexFromArr(Context.TxProof.SmartHash))
|
||||
ToLog("Write AccHash:" + GetHexFromArr(Params.AccHash))
|
||||
ToLog("Write SmartHash:" + GetHexFromArr(Params.SmartHash))
|
||||
Context.Mode = 100
|
||||
}
|
||||
})
|
||||
Context.Mode++
|
||||
ToLog("Next mode: " + Context.Mode, 2)
|
||||
break;
|
||||
case 10:
|
||||
break;
|
||||
case 11:
|
||||
var Context2 = this.LoadHistoryContext;
|
||||
Context2.BlockNum = this.LoadRestContext.BlockNumRest
|
||||
Context2.StartTimeHistory = Date.now()
|
||||
Context.Mode = 200
|
||||
break;
|
||||
case 200:
|
||||
ToLog("Error state!")
|
||||
break;
|
||||
}
|
||||
}
|
||||
RETBLOCKHEADER_REST(Info, CurTime)
|
||||
{
|
||||
var Context = this.LoadRestContext;
|
||||
var BufRead = BufLib.GetReadBuffer(Info.Data);
|
||||
var arr = this.GetBlockArrFromBuffer_Load(BufRead, Info);
|
||||
ToLog("RETBLOCKHEADER_FOWARD SyncRest from " + NodeName(Info.Node) + " arr=" + arr.length, 2)
|
||||
Context.ReceiveHeaderCount++
|
||||
var MinSumPow = 10 * Context.CountProof;
|
||||
var SumPower = 0;
|
||||
if(arr.length >= Context.CountProof)
|
||||
for(var i = 0; i < Context.CountProof; i++)
|
||||
{
|
||||
SumPower += arr[i].Power
|
||||
}
|
||||
if(SumPower <= MinSumPow)
|
||||
SumPower = 0
|
||||
Context.ArrProof.push({Node:Info.Node, SumPower:SumPower, arr:arr, BufRead:BufRead})
|
||||
}
|
||||
static
|
||||
GETSMART_F()
|
||||
{
|
||||
return "{\
|
||||
SmartNum:uint,\
|
||||
Count:uint,\
|
||||
}";
|
||||
}
|
||||
static
|
||||
RETSMART_F()
|
||||
{
|
||||
return global.FORMAT_SMART_TRANSFER;
|
||||
}
|
||||
static
|
||||
GETREST_F()
|
||||
{
|
||||
return "{\
|
||||
BlockNum:uint,\
|
||||
AccNum:uint,\
|
||||
Count:uint,\
|
||||
}";
|
||||
}
|
||||
static
|
||||
RETREST_F()
|
||||
{
|
||||
return global.FORMAT_REST_TRANSFER;
|
||||
}
|
||||
};
|
||||
|
||||
function CheckHashSmarts(LastSumHash)
|
||||
{
|
||||
DApps.Smart.Close();
|
||||
var MaxNum = DApps.Smart.GetMaxNum();
|
||||
var Item = DApps.Smart.DBSmart.Read(MaxNum);
|
||||
if(CompareArr(Item.SumHash, LastSumHash) !== 0)
|
||||
return MaxNum;
|
||||
var WorkStruct = {};
|
||||
for(var Num = MaxNum; Num >= 1; Num--)
|
||||
{
|
||||
var PrevItem = DApps.Smart.DBSmart.Read(Num - 1);
|
||||
if(!PrevItem)
|
||||
return Num;
|
||||
var WasSumHash = Item.SumHash;
|
||||
Item.SumHash = [];
|
||||
var Buf = BufLib.GetBufferFromObject(Item, DApps.Smart.FORMAT_ROW, 20000, WorkStruct);
|
||||
var Hash = sha3(Buf);
|
||||
var SumHash = sha3arr2(PrevItem.SumHash, Hash);
|
||||
if(CompareArr(SumHash, WasSumHash) !== 0)
|
||||
return Num;
|
||||
Item = PrevItem;
|
||||
}
|
||||
return 0;
|
||||
};
|
73
Source/core/rest_tables.js
Normal file
73
Source/core/rest_tables.js
Normal file
@ -0,0 +1,73 @@
|
||||
/*
|
||||
* @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
|
||||
*/
|
||||
|
||||
|
||||
function DoRest(r,t,e)
|
||||
{
|
||||
var u = r.Arr[0], o = Math.floor(e / REST_BLOCK_SCALE);
|
||||
if(o !== Math.floor((u.BlockNum - 1) / REST_BLOCK_SCALE))
|
||||
{
|
||||
for(var n = GetRestArr(o), l = [], a = n.length - 2; 0 <= a; a--)
|
||||
l.push(n[a] * REST_BLOCK_SCALE);
|
||||
RestPush(r, l, e, 1);
|
||||
}
|
||||
r.Arr[0] = {BlockNum:e, Value:t.Value};
|
||||
};
|
||||
|
||||
function RestPush(r,t,e,u)
|
||||
{
|
||||
var o = r.Arr[u - 1], n = r.Arr[u];
|
||||
if(1 < u)
|
||||
{
|
||||
var l = t[u - 2];
|
||||
if(o.BlockNum > l)
|
||||
return ;
|
||||
}
|
||||
if(n.BlockNum && n.BlockNum >= e || o.BlockNum >= e)
|
||||
return n.BlockNum = 0, void (n.Value = {});
|
||||
n.BlockNum && u < r.Arr.length - 1 && RestPush(r, t, e, u + 1), r.Arr[u] = o;
|
||||
};
|
||||
|
||||
function GetRestArr(r)
|
||||
{
|
||||
for(var t = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0], e = t.length, u = 0; u <= r; u++)
|
||||
for(var o = 0, n = u, l = e - 1; 0 <= l; l--)
|
||||
{
|
||||
var a = t[l];
|
||||
if(t[l] = n, n = a, 0 == ((o = o << 4 | 15) & u))
|
||||
break;
|
||||
if(0 != (o & n))
|
||||
break;
|
||||
}
|
||||
return t;
|
||||
};
|
||||
var RestArrMap = {};
|
||||
|
||||
function GetCurrentRestArr()
|
||||
{
|
||||
var r = GetCurrentBlockNumByTime(), t = Math.floor(r / REST_BLOCK_SCALE), e = RestArrMap[t];
|
||||
if(void 0 === e)
|
||||
{
|
||||
RestArrMap = {}, e = GetRestArr(t);
|
||||
for(var u = 0; u < e.length; u++)
|
||||
e[u] = e[u] * REST_BLOCK_SCALE;
|
||||
RestArrMap[t] = e;
|
||||
}
|
||||
return e;
|
||||
};
|
||||
|
||||
function GetCurrentRestNum(r)
|
||||
{
|
||||
for(var t = GetCurrentBlockNumByTime() - r, e = GetCurrentRestArr(), u = e.length - 1; 0 <= u; u--)
|
||||
if(e[u] <= t)
|
||||
return e[u];
|
||||
return 0;
|
||||
};
|
||||
global.DoRest = DoRest, global.GetRestArr = GetRestArr, global.GetCurrentRestArr = GetCurrentRestArr, global.GetCurrentRestNum = GetCurrentRestNum;
|
@ -121,8 +121,10 @@ module.exports = class CTransport extends require("./connect")
|
||||
Map["RETBLOCKHEADER"] = {Period:0}
|
||||
Map["RETGETBLOCK"] = {Period:0}
|
||||
Map["RETCODE"] = {Period:0}
|
||||
Map["GETREST"] = {Period:1000, Hard:1}
|
||||
Map["GETREST"] = {Period:1000, Hard:2, Process:global.STATIC_PROCESS}
|
||||
Map["RETREST"] = {Period:0}
|
||||
Map["GETSMART"] = {Period:1000, Hard:2, Process:global.STATIC_PROCESS}
|
||||
Map["RETSMART"] = {Period:0}
|
||||
}
|
||||
if(!this.VirtualMode)
|
||||
this.StartServer()
|
||||
@ -249,6 +251,12 @@ module.exports = class CTransport extends require("./connect")
|
||||
return ;
|
||||
}
|
||||
Info.Node.LastTime = CurTime - 0
|
||||
if(Info.Context && typeof Info.Context.F === "function")
|
||||
{
|
||||
Info.Context.F(Info, CurTime)
|
||||
}
|
||||
else
|
||||
{
|
||||
var F = this[Info.Method.toUpperCase()];
|
||||
if(typeof F === "function")
|
||||
{
|
||||
@ -260,6 +268,7 @@ module.exports = class CTransport extends require("./connect")
|
||||
this.AddCheckErrCount(Info.Node, 1, "Method not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
GetActualNodes()
|
||||
{
|
||||
var Arr = [];
|
||||
|
@ -213,7 +213,8 @@ module.exports = class CSmartContract extends require("./block-exchange")
|
||||
ToLog("Cant rewrite transactions. Very long length of the rewriting chain. Max length=" + (this.BlockNumDB - MinBlock))
|
||||
return 0;
|
||||
}
|
||||
TX_PROCESS.Worker.send({cmd:"ReWriteDAppTransactions", StartNum:StartNum, EndNum:EndNum})
|
||||
if(global.TX_PROCESS && global.TX_PROCESS.RunRPC)
|
||||
global.TX_PROCESS.RunRPC("ReWriteDAppTransactions", {StartNum:StartNum, EndNum:EndNum})
|
||||
return 1;
|
||||
}
|
||||
AddDAppTransactions(BlockNum, Arr)
|
||||
@ -223,19 +224,24 @@ module.exports = class CSmartContract extends require("./block-exchange")
|
||||
var BlockNumHash = BlockNum - DELTA_BLOCK_ACCOUNT_HASH;
|
||||
if(BlockNumHash < 0)
|
||||
return ;
|
||||
var Hash = DApps.Accounts.GetHashOrUndefined(BlockNumHash);
|
||||
if(Hash)
|
||||
var Item = DApps.Accounts.GetAccountHashItem(BlockNumHash);
|
||||
if(Item)
|
||||
{
|
||||
var Body = [TYPE_TRANSACTION_ACC_HASH];
|
||||
WriteUintToArr(Body, BlockNumHash)
|
||||
WriteArrToArr(Body, Hash, 32)
|
||||
WriteArrToArr(Body, Item.AccHash, 32)
|
||||
if(BlockNumHash >= START_BLOCK_ACCOUNT_HASH3)
|
||||
{
|
||||
WriteUintToArr(Body, Item.AccountMax)
|
||||
WriteArrToArr(Body, Item.SmartHash, 32)
|
||||
WriteUintToArr(Body, Item.SmartCount)
|
||||
WriteUintToArr(Body, BlockNum)
|
||||
WriteUintToArr(Body, 0)
|
||||
}
|
||||
var Tr = {body:Body};
|
||||
this.CheckCreateTransactionObject(Tr)
|
||||
Arr.unshift(Tr)
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
AddTransactionOwn(Tr)
|
||||
{
|
||||
|
@ -11,7 +11,7 @@
|
||||
"use strict";
|
||||
const fs = require('fs');
|
||||
const DBRow = require("../core/db/db-row");
|
||||
require('./rest_tables.js');
|
||||
require('../core/rest_tables.js');
|
||||
const MAX_SUM_TER = 1e9;
|
||||
const MAX_SUM_CENT = 1e9;
|
||||
const DBLib = require("../core/db/db");
|
||||
@ -71,7 +71,15 @@ global.FORMAT_MONEY_TRANSFER_BODY3 = FORMAT_MONEY_TRANSFER3.replace("Sign:arr64,
|
||||
global.FORMAT_ACCOUNT_HASH = "{\
|
||||
Type:byte,\
|
||||
BlockNum:uint,\
|
||||
Hash:buffer32,\
|
||||
AccHash:buffer32,\
|
||||
}";
|
||||
global.FORMAT_ACCOUNT_HASH3 = "{\
|
||||
Type:byte,\
|
||||
BlockNum:uint,\
|
||||
AccHash:buffer32,\
|
||||
AccountMax:uint,\
|
||||
SmartHash:buffer32,\
|
||||
SmartCount:uint,\
|
||||
}";
|
||||
class MerkleDBRow extends DBRow
|
||||
{
|
||||
@ -164,9 +172,9 @@ class AccountApp extends require("./dapp")
|
||||
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}"]
|
||||
if(global.READ_ONLY_DB)
|
||||
return ;
|
||||
this.DBAccountsHash = new DBRow("accounts-hash2", 6 + 32 + 32 + 10, "{BlockNum:uint, Hash:hash, SumHash:hash, Reserve: arr10}",
|
||||
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 + 94, "{BlockNum:uint, Reserve: arr94}", bReadOnly)
|
||||
this.DBStateTX = new DBRow("accounts-tx", 6 + 6 + 88, "{BlockNum:uint, BlockNumMin:uint, Reserve: arr88}", bReadOnly)
|
||||
if(global.START_SERVER)
|
||||
return ;
|
||||
if(!bReadOnly)
|
||||
@ -379,6 +387,7 @@ class AccountApp extends require("./dapp")
|
||||
}
|
||||
case TYPE_TRANSACTION_ACC_HASH:
|
||||
{
|
||||
Result = 1
|
||||
if(global.LOCAL_RUN || global.TEST_NETWORK);
|
||||
else
|
||||
if(BlockNum < START_BLOCK_ACCOUNT_HASH + 200000)
|
||||
@ -392,8 +401,6 @@ class AccountApp extends require("./dapp")
|
||||
else
|
||||
{
|
||||
Result = true
|
||||
this.NexdDeltaAccountNum = DELTA_BLOCK_ACCOUNT_HASH
|
||||
SERVER.LastNumAccountHashOK = BlockNumHash
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -485,7 +492,7 @@ class AccountApp extends require("./dapp")
|
||||
}
|
||||
case TYPE_TRANSACTION_ACC_HASH:
|
||||
{
|
||||
format = FORMAT_ACCOUNT_HASH
|
||||
format = FORMAT_ACCOUNT_HASH3
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -523,7 +530,7 @@ class AccountApp extends require("./dapp")
|
||||
return 1;
|
||||
try
|
||||
{
|
||||
var TR = BufLib.GetObjectFromBuffer(Body, FORMAT_ACCOUNT_HASH, {});
|
||||
var TR = BufLib.GetObjectFromBuffer(Body, FORMAT_ACCOUNT_HASH3, {});
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
@ -532,10 +539,21 @@ class AccountApp extends require("./dapp")
|
||||
if(BlockNum < START_BLOCK_ACCOUNT_HASH + 200000)
|
||||
return 1;
|
||||
var Item = this.GetAccountHashItem(TR.BlockNum);
|
||||
if(Item)
|
||||
if(Item && Item.BlockNum === TR.BlockNum)
|
||||
{
|
||||
if(CompareArr(Item.AccHash, TR.AccHash) === 0)
|
||||
{
|
||||
if(TR.BlockNum >= START_BLOCK_ACCOUNT_HASH3)
|
||||
{
|
||||
if(CompareArr(Item.SmartHash, TR.SmartHash) === 0 && Item.AccountMax === TR.AccountMax && Item.SmartCount === TR.SmartCount)
|
||||
{
|
||||
if(CompareArr(Item.Hash, TR.Hash) === 0)
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
@ -573,6 +591,10 @@ class AccountApp extends require("./dapp")
|
||||
{
|
||||
power = GetPowPower(shaarr(Body))
|
||||
}
|
||||
if(global.TEST_NETWORK && BlockNum >= 3290000)
|
||||
{
|
||||
CheckMinPower = 0
|
||||
}
|
||||
if(CheckMinPower && BlockNum < 19600000)
|
||||
{
|
||||
var MinPower;
|
||||
@ -810,7 +832,11 @@ class AccountApp extends require("./dapp")
|
||||
if(global.START_SERVER)
|
||||
throw "DeleteAct START_SERVER";
|
||||
if(BlockNumFrom > 0)
|
||||
this.DBStateTX.Write({Num:0, BlockNum:BlockNumFrom - 1})
|
||||
{
|
||||
var StateTX = this.DBStateTX.Read(0);
|
||||
StateTX.BlockNum = BlockNumFrom - 1
|
||||
this.DBStateTX.Write(StateTX)
|
||||
}
|
||||
this.DeleteActOneDB(this.DBAct, BlockNumFrom)
|
||||
this.DeleteActOneDB(this.DBActPrev, BlockNumFrom)
|
||||
this.DBAccountsHash.Truncate(Math.trunc(BlockNumFrom / PERIOD_ACCOUNT_HASH))
|
||||
@ -935,19 +961,13 @@ class AccountApp extends require("./dapp")
|
||||
if(Data.Value.Smart)
|
||||
{
|
||||
Data.SmartObj = DApps.Smart.ReadSimple(Data.Value.Smart)
|
||||
try
|
||||
{
|
||||
Data.SmartState = BufLib.GetObjectFromBuffer(Data.Value.Data, Data.SmartObj.StateFormat, {})
|
||||
if(typeof Data.SmartState === "object")
|
||||
Data.SmartState.Num = Num
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
if(Data.SmartObj)
|
||||
Data.SmartState = this.GetSmartState(Data, Data.SmartObj.StateFormat)
|
||||
else
|
||||
Data.SmartState = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
GetMaxAccount()
|
||||
@ -1032,23 +1052,12 @@ class AccountApp extends require("./dapp")
|
||||
if(Data.Value.Smart)
|
||||
{
|
||||
Data.SmartObj = DApps.Smart.ReadSimple(Data.Value.Smart)
|
||||
try
|
||||
{
|
||||
Data.SmartState = BufLib.GetObjectFromBuffer(Data.Value.Data, Data.SmartObj.StateFormat, {})
|
||||
if(typeof Data.SmartState === "object")
|
||||
Data.SmartState.Num = num
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
if(Data.SmartObj)
|
||||
Data.SmartState = this.GetSmartState(Data, Data.SmartObj.StateFormat)
|
||||
else
|
||||
Data.SmartState = {}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(global.TEST_NETWORK)
|
||||
{
|
||||
var RestData = this.ReadRest(Data.Num);
|
||||
Data.Arr = RestData.Arr
|
||||
}
|
||||
arr.push(Data)
|
||||
count--
|
||||
if(count < 1)
|
||||
@ -1056,6 +1065,21 @@ class AccountApp extends require("./dapp")
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
GetSmartState(StateData, StateFormat)
|
||||
{
|
||||
var SmartState;
|
||||
try
|
||||
{
|
||||
SmartState = BufLib.GetObjectFromBuffer(StateData.Value.Data, StateFormat, {})
|
||||
if(typeof SmartState === "object")
|
||||
SmartState.Num = StateData.Num
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
SmartState = {}
|
||||
}
|
||||
return SmartState;
|
||||
}
|
||||
GetActsMaxNum()
|
||||
{
|
||||
return this.DBActPrev.GetMaxNum() + this.DBAct.GetMaxNum();
|
||||
@ -1097,7 +1121,7 @@ class AccountApp extends require("./dapp")
|
||||
return undefined;
|
||||
var Item = this.GetAccountHashItem(BlockNum);
|
||||
if(Item)
|
||||
return Item.Hash;
|
||||
return Item.AccHash;
|
||||
else
|
||||
return undefined;
|
||||
}
|
||||
@ -1117,7 +1141,7 @@ class AccountApp extends require("./dapp")
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
CalcHash(Block)
|
||||
CalcHash(Block, BlockMaxAccount)
|
||||
{
|
||||
if(Block.BlockNum % PERIOD_ACCOUNT_HASH !== 0)
|
||||
return ;
|
||||
@ -1126,9 +1150,22 @@ class AccountApp extends require("./dapp")
|
||||
this.CalcMerkleTree()
|
||||
}
|
||||
var Hash = this.DBState.MerkleHash;
|
||||
var Data = {Num:Block.BlockNum / PERIOD_ACCOUNT_HASH, BlockNum:Block.BlockNum, Hash:Hash, SumHash:Block.SumHash};
|
||||
var SmartHash;
|
||||
var SmartCount = DApps.Smart.GetMaxNum() + 1;
|
||||
if(SmartCount > 0)
|
||||
{
|
||||
var MaxSmart = DApps.Smart.DBSmart.Read(SmartCount - 1);
|
||||
SmartHash = MaxSmart.SumHash
|
||||
}
|
||||
else
|
||||
{
|
||||
SmartHash = []
|
||||
}
|
||||
var Data = {Num:Block.BlockNum / PERIOD_ACCOUNT_HASH, BlockNum:Block.BlockNum, AccHash:Hash, SumHash:Block.SumHash, AccountMax:BlockMaxAccount,
|
||||
SmartHash:SmartHash, SmartCount:SmartCount};
|
||||
this.DBAccountsHash.Write(Data)
|
||||
this.DBAccountsHash.Truncate(Block.BlockNum / PERIOD_ACCOUNT_HASH)
|
||||
return Data;
|
||||
}
|
||||
CalcMerkleTree(bForce)
|
||||
{
|
||||
@ -1223,14 +1260,10 @@ class AccountApp extends require("./dapp")
|
||||
}
|
||||
global.TickCounter = 0
|
||||
this.DBChanges = undefined
|
||||
if(BlockNum > 100)
|
||||
{
|
||||
this.CalcHash(Block, DBChanges.BlockMaxAccount)
|
||||
var StateTX = this.DBStateTX.Read(0);
|
||||
if(StateTX.BlockNum !== BlockNum - 1)
|
||||
throw "ERROR SEQ STATETX";
|
||||
}
|
||||
this.CalcHash(Block)
|
||||
this.DBStateTX.Write({Num:0, BlockNum:BlockNum})
|
||||
StateTX.BlockNum = BlockNum
|
||||
this.DBStateTX.Write(StateTX)
|
||||
}
|
||||
CommitTransaction(BlockNum, TrNum)
|
||||
{
|
||||
@ -1425,8 +1458,11 @@ class AccountApp extends require("./dapp")
|
||||
}
|
||||
return Position;
|
||||
}
|
||||
GetHistory(Num, Count, StartPos)
|
||||
GetHistory(Num, Count, StartPos, MinConfirm)
|
||||
{
|
||||
if(!MinConfirm)
|
||||
MinConfirm = 0
|
||||
var MaxNumBlockDB = SERVER.GetMaxNumBlockDB();
|
||||
var Position = StartPos;
|
||||
var FileItem = HistoryDB.OpenDBFile(FILE_NAME_HISTORY, 0);
|
||||
var FD = FileItem.fd;
|
||||
@ -1460,6 +1496,13 @@ class AccountApp extends require("./dapp")
|
||||
var Item = BufLib.GetObjectFromBuffer(BufRead, format, WorkStructHistory);
|
||||
Item.Pos = Position
|
||||
Position = Item.NextPos
|
||||
if(MinConfirm)
|
||||
{
|
||||
if(Item.BlockNum + MinConfirm > MaxNumBlockDB)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
arr.push(Item)
|
||||
}
|
||||
return arr;
|
||||
|
@ -87,6 +87,7 @@ class SmartApp extends require("./dapp")
|
||||
Description:str,\
|
||||
Code:str,\
|
||||
HTML:str,\
|
||||
SumHash:hash,\
|
||||
}"
|
||||
this.ROW_SIZE = 2 * (1 << 13)
|
||||
this.DBSmart = new DBRow("smart", this.ROW_SIZE, this.FORMAT_ROW, bReadOnly)
|
||||
@ -96,11 +97,15 @@ class SmartApp extends require("./dapp")
|
||||
}
|
||||
Start()
|
||||
{
|
||||
if(this.DBSmart.GetMaxNum() + 1 >= 7)
|
||||
if(this.GetMaxNum() + 1 >= 7)
|
||||
return ;
|
||||
this.DBSmart.Write({Num:0, ShortName:"TERA", Name:"TERA", Description:"TERA", BlockNum:0, TokenGenerate:1, Account:0, Category1:0})
|
||||
this.DBSmartWrite({Num:0, ShortName:"TERA", Name:"TERA", Description:"TERA", BlockNum:0, TokenGenerate:1, Account:0, Category1:0})
|
||||
for(var i = 1; i < 8; i++)
|
||||
this.DBSmart.Write({Num:i, ShortName:"", Name:"", Description:"", BlockNum:0, TokenGenerate:1, Account:i, Category1:0})
|
||||
this.DBSmartWrite({Num:i, ShortName:"", Name:"", Description:"", BlockNum:0, TokenGenerate:1, Account:i, Category1:0})
|
||||
}
|
||||
Close()
|
||||
{
|
||||
this.DBSmart.Close()
|
||||
}
|
||||
ClearDataBase()
|
||||
{
|
||||
@ -244,7 +249,7 @@ class SmartApp extends require("./dapp")
|
||||
this.DBSmart.DeleteMap("EVAL" + Smart.Num)
|
||||
return e;
|
||||
}
|
||||
this.DBSmart.Write(Smart)
|
||||
this.DBSmartWrite(Smart)
|
||||
return true;
|
||||
}
|
||||
CheckSignFrom(Body, TR, BlockNum, TrNum)
|
||||
@ -329,7 +334,7 @@ class SmartApp extends require("./dapp")
|
||||
return ResultCheck;
|
||||
ContextFrom = ResultCheck
|
||||
}
|
||||
if(TR.Smart > DApps.Smart.GetMaxNum())
|
||||
if(TR.Smart > this.GetMaxNum())
|
||||
TR.Smart = 0
|
||||
if(ContextFrom.FromID !== TR.Account)
|
||||
return "ChangeSmart: Error account FromNum: " + TR.Account;
|
||||
@ -408,7 +413,18 @@ class SmartApp extends require("./dapp")
|
||||
if(Str.indexOf(Filter) < 0)
|
||||
continue;
|
||||
}
|
||||
var CanAdd = 1;
|
||||
var DataState = DApps.Accounts.ReadState(Data.Account);
|
||||
if(DataState && !global.ALL_VIEW_ROWS)
|
||||
{
|
||||
Data.BaseState = DApps.Accounts.GetSmartState(DataState, Data.StateFormat)
|
||||
if(typeof Data.BaseState === "object" && Data.BaseState.HTMLBlock === 404)
|
||||
CanAdd = 0
|
||||
}
|
||||
if(CanAdd)
|
||||
{
|
||||
arr.push(Data)
|
||||
}
|
||||
count--
|
||||
if(count < 1)
|
||||
break;
|
||||
@ -419,6 +435,29 @@ class SmartApp extends require("./dapp")
|
||||
{
|
||||
return this.DBSmart.GetMaxNum();
|
||||
}
|
||||
DBSmartWrite(Item)
|
||||
{
|
||||
var PrevNum;
|
||||
if(Item.Num === undefined)
|
||||
PrevNum = this.GetMaxNum()
|
||||
else
|
||||
PrevNum = Item.Num - 1
|
||||
Item.SumHash = []
|
||||
var Buf = BufLib.GetBufferFromObject(Item, this.FORMAT_ROW, 20000, {});
|
||||
var Hash = sha3(Buf);
|
||||
if(PrevNum < 0)
|
||||
Item.SumHash = Hash
|
||||
else
|
||||
{
|
||||
var PrevItem = this.DBSmart.Read(PrevNum);
|
||||
if(!PrevItem)
|
||||
{
|
||||
throw "!PrevItem of Smart num = " + PrevNum;
|
||||
}
|
||||
Item.SumHash = sha3arr2(PrevItem.SumHash, Hash)
|
||||
}
|
||||
this.DBSmart.Write(Item)
|
||||
}
|
||||
ReadSmart(Num)
|
||||
{
|
||||
Num = ParseNum(Num)
|
||||
@ -554,6 +593,12 @@ function RunSmartMethod(Block,SmartOrSmartID,Account,BlockNum,TrNum,PayContext,M
|
||||
if(PayContext.Value)
|
||||
context.Value = {SumCOIN:PayContext.Value.SumCOIN, SumCENT:PayContext.Value.SumCENT};
|
||||
}
|
||||
if(BlockNum === 0)
|
||||
{
|
||||
context.GetBlockHeader = StaticGetBlockHeader;
|
||||
context.GetBlockNumDB = StaticGetBlockNumDB;
|
||||
context.GetSmart = StaticGetSmart;
|
||||
}
|
||||
var LocalRunContext = {Block:Block, Smart:Smart, Account:Account, BlockNum:BlockNum, TrNum:TrNum, context:context};
|
||||
var RetValue;
|
||||
var _RunContext = RunContext;
|
||||
@ -1315,6 +1360,24 @@ function random()
|
||||
RunContext.Block.Hash;
|
||||
return 0;
|
||||
};
|
||||
|
||||
function StaticGetBlockHeader(BlockNum)
|
||||
{
|
||||
DO(100);
|
||||
return SERVER.ReadBlockHeaderDB(BlockNum);
|
||||
};
|
||||
|
||||
function StaticGetBlockNumDB()
|
||||
{
|
||||
return SERVER.GetMaxNumBlockDB();
|
||||
};
|
||||
|
||||
function StaticGetSmart(Num)
|
||||
{
|
||||
DO(100);
|
||||
var Smart = DApps.Smart.ReadSmart(Num);
|
||||
return GET_SMART(Smart);
|
||||
};
|
||||
ChangePrototype();
|
||||
InitEval();
|
||||
module.exports = SmartApp;
|
||||
|
@ -158,7 +158,9 @@ WebApi2.GetHistoryTransactions = function (Params)
|
||||
{
|
||||
if(!Params.Count)
|
||||
Params.Count = 100;
|
||||
var arr = DApps.Accounts.GetHistory(Params.AccountID, Params.Count, Params.NextPos);
|
||||
if(Params.Confirm === undefined)
|
||||
Params.Confirm = 8;
|
||||
var arr = DApps.Accounts.GetHistory(Params.AccountID, Params.Count, Params.NextPos, Params.Confirm);
|
||||
if(Params.GetTxID || Params.GetDescription)
|
||||
{
|
||||
for(var i = 0; i < arr.length; i++)
|
||||
|
@ -8,43 +8,3 @@
|
||||
* Telegram: https://web.telegram.org/#/im?p=@terafoundation
|
||||
*/
|
||||
|
||||
var lastcoin = 1000000000;
|
||||
|
||||
function show()
|
||||
{
|
||||
if(global.DApps && GENERATE_BLOCK_ACCOUNT)
|
||||
{
|
||||
var arr = DApps.Accounts.GetRowsAccounts(GENERATE_BLOCK_ACCOUNT, 1);
|
||||
var Data = arr[0];
|
||||
if(!Data || !Data.Value)
|
||||
return ;
|
||||
var sumcoin = Data.Value.SumCOIN;
|
||||
var delta = sumcoin - lastcoin;
|
||||
lastcoin = sumcoin;
|
||||
if(delta > 200)
|
||||
{
|
||||
ToLog("ID:" + GENERATE_BLOCK_ACCOUNT);
|
||||
if(global.COREY_WATCH_DOG === 1)
|
||||
{
|
||||
ToLog("Its forked restart now");
|
||||
RestartNode();
|
||||
}
|
||||
else
|
||||
if(global.COREY_WATCH_DOG === 2)
|
||||
{
|
||||
SERVER.FREE_ALL_MEM_CHAINS();
|
||||
var Num = SERVER.BlockNumDB - 5000;
|
||||
if(Num < 100)
|
||||
Num = 100;
|
||||
lastcoin = 1000000000;
|
||||
ToLog("Its forked - truncate now from block: " + Num);
|
||||
SERVER.SetTruncateBlockDB(Num);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
if(global.COREY_WATCH_DOG)
|
||||
{
|
||||
ToLog("===START COREY_WATCH_DOG==");
|
||||
setInterval(show, 35000);
|
||||
}
|
||||
|
@ -73,7 +73,7 @@ process.on('error', function (err)
|
||||
});
|
||||
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:20 * 1000};
|
||||
OnMessage:OnMessageWeb, PeriodAlive:10 * 1000};
|
||||
if(global.HTTP_HOSTING_PORT && !global.NWMODE)
|
||||
{
|
||||
ArrChildProcess.push(WebProcess);
|
||||
@ -210,6 +210,9 @@ function StartChildProcess(Item)
|
||||
{
|
||||
let ITEM = Item;
|
||||
ITEM.idInterval = setInterval(function ()
|
||||
{
|
||||
var Delta0 = Date.now() - ITEM.LastAlive;
|
||||
if(Delta0 >= 0)
|
||||
{
|
||||
var Delta = Date.now() - ITEM.LastAlive;
|
||||
if(ITEM.Worker && Delta > ITEM.PeriodAlive)
|
||||
@ -223,6 +226,7 @@ function StartChildProcess(Item)
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
return ;
|
||||
}
|
||||
ITEM.Worker = undefined;
|
||||
}
|
||||
@ -242,9 +246,21 @@ function StartChildProcess(Item)
|
||||
var Err = 0;
|
||||
var Ret;
|
||||
try
|
||||
{
|
||||
if(typeof msg.Params === "object" && msg.Params.F)
|
||||
{
|
||||
global[msg.Name](msg.Params, function (Err,Ret)
|
||||
{
|
||||
if(msg.id && ITEM.Worker)
|
||||
ITEM.Worker.send({cmd:"retcall", id:msg.id, Err:Err, Params:Ret});
|
||||
});
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
Ret = global[msg.Name](msg.Params);
|
||||
}
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
Err = 1;
|
||||
@ -311,6 +327,7 @@ function StartChildProcess(Item)
|
||||
ITEM.Worker = undefined;
|
||||
});
|
||||
}
|
||||
}
|
||||
if(ITEM.Worker)
|
||||
{
|
||||
ITEM.Worker.send({cmd:"Alive"});
|
||||
@ -724,6 +741,14 @@ function RunOnUpdate()
|
||||
else
|
||||
{
|
||||
}
|
||||
if(CurNum < 933)
|
||||
{
|
||||
RecreateAccountHashDB3();
|
||||
}
|
||||
if(CurNum < 955)
|
||||
{
|
||||
ReWriteDBSmartWrite();
|
||||
}
|
||||
ToLog("UPDATER Finish");
|
||||
}
|
||||
};
|
||||
@ -835,6 +860,53 @@ function RecreateAccountRest1()
|
||||
fs.unlinkSync(fname);
|
||||
}
|
||||
};
|
||||
|
||||
function RecreateAccountHashDB3()
|
||||
{
|
||||
var name = "accounts-hash2";
|
||||
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 + 32 + 10, "{BlockNum:uint, Hash:hash, SumHash:hash, Reserve: arr10}");
|
||||
var DB3 = DApps.Accounts.DBAccountsHash;
|
||||
for(var num = 0; true; num++)
|
||||
{
|
||||
var Item = DB0.Read(num);
|
||||
if(!Item)
|
||||
break;
|
||||
Item.AccHash = Item.Hash;
|
||||
DB3.Write(Item);
|
||||
}
|
||||
ToLog("Finish updating " + name);
|
||||
DB0.Close();
|
||||
DB3.Close();
|
||||
global.UpdateMode = 0;
|
||||
fs.unlinkSync(fname);
|
||||
}
|
||||
};
|
||||
|
||||
function ReWriteDBSmartWrite()
|
||||
{
|
||||
global.UpdateMode = 1;
|
||||
ToLog("Start ReWriteDBSmartWrite");
|
||||
require("../core/db/db-row");
|
||||
for(var num = 0; true; num++)
|
||||
{
|
||||
var Item = DApps.Smart.DBSmart.Read(num);
|
||||
if(!Item)
|
||||
break;
|
||||
var Body = BufLib.GetBufferFromObject(Item, DApps.Smart.FORMAT_ROW, 20000, {});
|
||||
if(Body.length > 15000)
|
||||
ToLog("Smart " + Item.Num + ". " + Item.Name + " length=" + Body.length);
|
||||
DApps.Smart.DBSmartWrite(Item);
|
||||
}
|
||||
ToLog("Finish ReWriteDBSmartWrite");
|
||||
DApps.Smart.DBSmart.Close();
|
||||
global.UpdateMode = 0;
|
||||
};
|
||||
global.TestSignLib = TestSignLib;
|
||||
|
||||
function TestSignLib(MaxTime)
|
||||
|
@ -12,6 +12,10 @@ global.PROCESS_NAME = "STATIC";
|
||||
const crypto = require('crypto');
|
||||
const fs = require('fs');
|
||||
require("../core/constant");
|
||||
require('../core/block-loader-const');
|
||||
require('../core/rest_tables.js');
|
||||
require('../dapp/accounts.js');
|
||||
require('../dapp/smart.js');
|
||||
global.DATA_PATH = GetNormalPathString(global.DATA_PATH);
|
||||
global.CODE_PATH = GetNormalPathString(global.CODE_PATH);
|
||||
require("../core/library");
|
||||
@ -63,6 +67,9 @@ process.on('message', function (msg)
|
||||
case "GETREST":
|
||||
GETREST(msg);
|
||||
break;
|
||||
case "GETSMART":
|
||||
GETSMART(msg);
|
||||
break;
|
||||
}
|
||||
});
|
||||
|
||||
@ -101,6 +108,8 @@ setInterval(function ()
|
||||
{
|
||||
if(SERVER)
|
||||
SERVER.ClearBufMap();
|
||||
DApps.Accounts.Close();
|
||||
DApps.Smart.DBSmart.Close();
|
||||
global.BlockDB.CloseDBFile("block-header");
|
||||
global.BlockDB.CloseDBFile("block-body");
|
||||
}, 1000);
|
||||
@ -115,7 +124,7 @@ function GETBLOCKHEADER(msg)
|
||||
if(Foward)
|
||||
{
|
||||
var BlockDB = SERVER.ReadBlockHeaderDB(Data.BlockNum);
|
||||
if(BlockDB && BlockDB.SumHash && CompareArr(BlockDB.SumHash, LoadHash) === 0)
|
||||
if(BlockDB && BlockDB.SumHash && (CompareArr(BlockDB.SumHash, LoadHash) === 0 || IsZeroArr(LoadHash)))
|
||||
{
|
||||
StartNum = Data.BlockNum - BLOCK_PROCESSING_LENGTH2;
|
||||
if(StartNum < 0)
|
||||
@ -147,12 +156,6 @@ function GETBLOCKHEADER(msg)
|
||||
var BufWrite = SERVER.BlockChainToBuf(StartNum, StartNum, BlockNum);
|
||||
process.send({cmd:"Send", addrStr:msg.addrStr, Method:"RETBLOCKHEADER", Context:msg.Context, Data:BufWrite});
|
||||
};
|
||||
const Formats = {BLOCK_TRANSFER:"{\
|
||||
BlockNum:uint,\
|
||||
TreeHash:hash,\
|
||||
arrContent:[tr],\
|
||||
}",
|
||||
WRK_BLOCK_TRANSFER:{}, };
|
||||
|
||||
function GETBLOCK(msg)
|
||||
{
|
||||
@ -164,15 +167,11 @@ function GETBLOCK(msg)
|
||||
return ;
|
||||
}
|
||||
var BufWrite;
|
||||
var BlockDB = undefined;
|
||||
if(TreeHash && !IsZeroArr(TreeHash))
|
||||
{
|
||||
BlockDB = SERVER.ReadBlockDB(BlockNum);
|
||||
}
|
||||
var BlockDB = SERVER.ReadBlockDB(BlockNum);
|
||||
var StrSend;
|
||||
if(BlockDB && CompareArr(BlockDB.TreeHash, TreeHash) === 0)
|
||||
if(BlockDB && (CompareArr(BlockDB.TreeHash, TreeHash) === 0 || IsZeroArr(TreeHash)))
|
||||
{
|
||||
var BufWrite = BufLib.GetBufferFromObject(BlockDB, Formats.BLOCK_TRANSFER, MAX_PACKET_LENGTH, Formats.WRK_BLOCK_TRANSFER);
|
||||
var BufWrite = BufLib.GetBufferFromObject(BlockDB, FORMAT_BLOCK_TRANSFER, MAX_PACKET_LENGTH, WRK_BLOCK_TRANSFER);
|
||||
StrSend = "OK";
|
||||
var TreeHashTest = CalcTreeHashFromArrBody(BlockDB.BlockNum, BlockDB.arrContent);
|
||||
if(CompareArr(BlockDB.TreeHash, TreeHashTest) !== 0)
|
||||
@ -206,4 +205,102 @@ function GETCODE(msg)
|
||||
|
||||
function GETREST(msg)
|
||||
{
|
||||
var Data = msg.Data;
|
||||
if(!Data.BlockNum)
|
||||
return ;
|
||||
var BlockNumRest = Data.BlockNum;
|
||||
var arr = GetCurrentRestArr();
|
||||
var BufLength;
|
||||
var nResult = 0;
|
||||
for(var i = 0; i < arr.length; i++)
|
||||
{
|
||||
if(arr[i] === BlockNumRest)
|
||||
{
|
||||
nResult = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
var ArrRest = [];
|
||||
if(nResult)
|
||||
{
|
||||
var WorkStruct = {};
|
||||
var WorkFormat = DApps.Accounts.FORMAT_ACCOUNT_ROW;
|
||||
var WorkFormatLength = DApps.Accounts.SIZE_ACCOUNT_ROW;
|
||||
var Max = DApps.Accounts.DBState.GetMaxNum();
|
||||
var LengthAccount = Data.Count;
|
||||
if(LengthAccount > MAX_ACCOUNTS_TRANSFER)
|
||||
LengthAccount = MAX_ACCOUNTS_TRANSFER;
|
||||
var EndAccount = Data.AccNum + LengthAccount - 1;
|
||||
if(EndAccount > Max)
|
||||
EndAccount = Max;
|
||||
var FindItem;
|
||||
for(var Num = Data.AccNum; Num <= EndAccount; Num++)
|
||||
{
|
||||
FindItem = undefined;
|
||||
var RestData = DApps.Accounts.ReadRest(Num);
|
||||
var Data = DApps.Accounts.DBState.Read(Num);
|
||||
if(!Data)
|
||||
break;
|
||||
var CountZero = 0;
|
||||
for(var i = RestData.Arr.length - 1; i >= 0; i--)
|
||||
{
|
||||
var Item = RestData.Arr[i];
|
||||
if(!Item.BlockNum)
|
||||
{
|
||||
CountZero++;
|
||||
continue;
|
||||
}
|
||||
if(Item.BlockNum <= BlockNumRest)
|
||||
{
|
||||
if(!FindItem || Item.BlockNum > FindItem.BlockNum)
|
||||
{
|
||||
FindItem = Item;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(FindItem)
|
||||
{
|
||||
Data.Value = FindItem.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(CountZero !== RestData.Arr.length)
|
||||
continue;
|
||||
}
|
||||
var Buf = BufLib.GetBufferFromObject(Data, WorkFormat, WorkFormatLength, WorkStruct);
|
||||
ArrRest.push(Buf);
|
||||
}
|
||||
BufLength = 1000 + ArrRest.length * WorkFormatLength;
|
||||
}
|
||||
else
|
||||
{
|
||||
BufLength = 1000;
|
||||
}
|
||||
var Data2 = {Result:nResult, BlockNum:BlockNumRest, Arr:ArrRest};
|
||||
var BufWrite = BufLib.GetBufferFromObject(Data2, FORMAT_REST_TRANSFER, BufLength, {});
|
||||
process.send({cmd:"Send", addrStr:msg.addrStr, Method:"RETREST", Context:msg.Context, Data:BufWrite});
|
||||
};
|
||||
|
||||
function GETSMART(msg)
|
||||
{
|
||||
var Data = msg.Data;
|
||||
if(!Data.Count)
|
||||
return ;
|
||||
var BufLength = 1000;
|
||||
var SizeForSend = 200 * 1024;
|
||||
var Arr = [];
|
||||
for(var Num = Data.SmartNum; Num < Data.SmartNum + Data.Count; Num++)
|
||||
{
|
||||
var BufSmart = DApps.Smart.DBSmart.Read(Num, 1);
|
||||
if(!BufSmart)
|
||||
break;
|
||||
SizeForSend = SizeForSend - BufSmart.length;
|
||||
if(SizeForSend < 0)
|
||||
break;
|
||||
BufLength += BufSmart.length;
|
||||
Arr.push(BufSmart);
|
||||
}
|
||||
var Data2 = {Result:Arr.length ? 1 : 0, Arr:Arr};
|
||||
var BufWrite = BufLib.GetBufferFromObject(Data2, FORMAT_SMART_TRANSFER, BufLength, {});
|
||||
process.send({cmd:"Send", addrStr:msg.addrStr, Method:"RETSMART", Context:msg.Context, Data:BufWrite});
|
||||
};
|
||||
|
@ -62,12 +62,6 @@ process.on('message', function (msg)
|
||||
case "SetSmartEvent":
|
||||
global.TreeFindTX.SaveValue("Smart:" + msg.Smart, 1);
|
||||
break;
|
||||
case "RewriteAllTransactions":
|
||||
RewriteAllTransactions(msg);
|
||||
break;
|
||||
case "ReWriteDAppTransactions":
|
||||
ReWriteDAppTransactions(msg);
|
||||
break;
|
||||
case "Eval":
|
||||
EvalCode(msg.Code);
|
||||
break;
|
||||
@ -88,7 +82,7 @@ function CheckAlive()
|
||||
var Delta = Date.now() - LastAlive;
|
||||
if(Delta > 100 * 1000)
|
||||
{
|
||||
ToLog("TX-PROCESS: ALIVE TIMEOUT Stop and exit: " + Delta + "/" + global.CHECK_STOP_CHILD_PROCESS);
|
||||
ToLog("TX-PROCESS: ALIVE TIMEOUT Stop and exit: " + Delta);
|
||||
process.exit(0);
|
||||
return ;
|
||||
}
|
||||
@ -123,6 +117,7 @@ setInterval(function ()
|
||||
}, 10);
|
||||
var BlockTree = new STreeBuffer(30 * 1000, CompareItemHashSimple, "number");
|
||||
global.bShowDetail = 0;
|
||||
var MinimalValidBlock = 0;
|
||||
var LastBlockNum = undefined;
|
||||
|
||||
function DoTXProcess()
|
||||
@ -175,8 +170,12 @@ function FindMinimal()
|
||||
LastBlockNum = MaxNumBlockDB - 1;
|
||||
BlockTree.Clear();
|
||||
}
|
||||
for(var Num = LastBlockNum; Num--; Num > 0)
|
||||
if(LastBlockNum < MinimalValidBlock)
|
||||
LastBlockNum = MinimalValidBlock;
|
||||
for(var Num = LastBlockNum; Num--; Num >= 0)
|
||||
{
|
||||
if(Num < MinimalValidBlock)
|
||||
break;
|
||||
var Block = SERVER.ReadBlockHeaderDB(Num);
|
||||
if(!Block)
|
||||
{
|
||||
@ -198,13 +197,16 @@ function FindMinimal()
|
||||
if(Item && CompareArr(Item.SumHash, Block.SumHash) === 0)
|
||||
return Block;
|
||||
}
|
||||
if(MinimalValidBlock === 0)
|
||||
RewriteAllTransactions();
|
||||
Block = SERVER.ReadBlockHeaderDB(0);
|
||||
Block = SERVER.ReadBlockHeaderDB(MinimalValidBlock);
|
||||
return Block;
|
||||
};
|
||||
|
||||
function IsValidSumHash(Block)
|
||||
{
|
||||
if(Block.BlockNum <= MinimalValidBlock + BLOCK_PROCESSING_LENGTH2)
|
||||
return 1;
|
||||
if(Block.BlockNum < 16)
|
||||
return 1;
|
||||
if(IsZeroArr(Block.SumHash))
|
||||
@ -233,11 +235,12 @@ function InitTXProcess()
|
||||
LastBlockNum = Item.BlockNum;
|
||||
}
|
||||
}
|
||||
ToLog("DETECT NEW VER on BlockNum=" + LastBlockNum);
|
||||
DApps.Accounts.DBStateTX.Write({Num:0, BlockNum:LastBlockNum});
|
||||
ToLog("DETECT NEW VER on BlockNum=" + LastBlockNum, 2);
|
||||
DApps.Accounts.DBStateTX.Write({Num:0, BlockNum:LastBlockNum, BlockNumMin:MinimalValidBlock});
|
||||
}
|
||||
StateTX = DApps.Accounts.DBStateTX.Read(0);
|
||||
LastBlockNum = StateTX.BlockNum;
|
||||
MinimalValidBlock = StateTX.BlockNumMin;
|
||||
LastBlockNum = PERIOD_ACCOUNT_HASH * Math.trunc(LastBlockNum / PERIOD_ACCOUNT_HASH);
|
||||
if(LastBlockNum > 100)
|
||||
{
|
||||
@ -246,12 +249,30 @@ function InitTXProcess()
|
||||
if(LastBlockNum <= 0)
|
||||
RewriteAllTransactions();
|
||||
else
|
||||
ToLog("Start NUM = " + LastBlockNum);
|
||||
ToLog("Start NUM = " + LastBlockNum, 2);
|
||||
DApps.Accounts.CalcMerkleTree();
|
||||
};
|
||||
global.ClearDataBase = ClearDataBase;
|
||||
|
||||
function ClearDataBase()
|
||||
{
|
||||
MinimalValidBlock = 0;
|
||||
for(var key in DApps)
|
||||
{
|
||||
DApps[key].ClearDataBase();
|
||||
}
|
||||
LastBlockNum = 0;
|
||||
BlockTree.Clear();
|
||||
};
|
||||
global.RewriteAllTransactions = RewriteAllTransactions;
|
||||
|
||||
function RewriteAllTransactions()
|
||||
{
|
||||
if(MinimalValidBlock > 0)
|
||||
{
|
||||
ToLog("*************Cant run RewriteAllTransactions, MinimalValidBlock:" + MinimalValidBlock, 2);
|
||||
return ;
|
||||
}
|
||||
ToLog("*************RewriteAllTransactions");
|
||||
for(var key in DApps)
|
||||
{
|
||||
@ -259,19 +280,80 @@ function RewriteAllTransactions()
|
||||
}
|
||||
LastBlockNum = 0;
|
||||
BlockTree.Clear();
|
||||
ToLog("Start num = " + LastBlockNum);
|
||||
ToLog("Start num = " + LastBlockNum, 2);
|
||||
};
|
||||
global.ReWriteDAppTransactions = ReWriteDAppTransactions;
|
||||
|
||||
function ReWriteDAppTransactions(msg)
|
||||
function ReWriteDAppTransactions(Params)
|
||||
{
|
||||
var StartNum = msg.StartNum;
|
||||
var EndNum = msg.EndNum;
|
||||
var StartNum = Params.StartNum;
|
||||
var EndNum = Params.EndNum;
|
||||
ToLog("ReWriteDAppTransactions: " + StartNum + " - " + EndNum);
|
||||
BlockTree.Clear();
|
||||
if(StartNum < LastBlockNum)
|
||||
LastBlockNum = StartNum;
|
||||
ToLog("Start num = " + LastBlockNum);
|
||||
ToLog("Start num = " + LastBlockNum, 2);
|
||||
};
|
||||
|
||||
function TXPrepareLoadRest(BlockNum)
|
||||
{
|
||||
MinimalValidBlock = BlockNum;
|
||||
ToLog("*************TXPrepareLoadRest:" + BlockNum, 2);
|
||||
for(var key in DApps)
|
||||
{
|
||||
DApps[key].ClearDataBase();
|
||||
}
|
||||
LastBlockNum = BlockNum;
|
||||
BlockTree.Clear();
|
||||
DApps.Accounts.DBStateTX.Write({Num:0, BlockNum:LastBlockNum, BlockNumMin:LastBlockNum});
|
||||
};
|
||||
global.TXPrepareLoadRest = TXPrepareLoadRest;
|
||||
|
||||
function TXWriteAccArr(Params)
|
||||
{
|
||||
var WorkStruct = {};
|
||||
var WorkFormat = DApps.Accounts.FORMAT_ACCOUNT_ROW;
|
||||
ToLog("Write accounts: " + Params.StartNum + "-" + Params.Arr.length, 2);
|
||||
for(var i = 0; i < Params.Arr.length; i++)
|
||||
{
|
||||
var Data = BufLib.GetObjectFromBuffer(Params.Arr[i], WorkFormat, WorkStruct);
|
||||
Data.Num = Params.StartNum + i;
|
||||
DApps.Accounts._DBStateWrite(Data, MinimalValidBlock);
|
||||
}
|
||||
};
|
||||
global.TXWriteAccArr = TXWriteAccArr;
|
||||
|
||||
function TXWriteSmartArr(Params)
|
||||
{
|
||||
var WorkStruct = {};
|
||||
var WorkFormat = DApps.Smart.FORMAT_ROW;
|
||||
ToLog("Write smarts: " + Params.StartNum + "-" + Params.Arr.length, 2);
|
||||
for(var i = 0; i < Params.Arr.length; i++)
|
||||
{
|
||||
var Data = BufLib.GetObjectFromBuffer(Params.Arr[i], WorkFormat, WorkStruct);
|
||||
Data.Num = Params.StartNum + i;
|
||||
DApps.Smart.DBSmart.Write(Data);
|
||||
}
|
||||
};
|
||||
global.TXWriteSmartArr = TXWriteSmartArr;
|
||||
|
||||
function TXWriteAccHash()
|
||||
{
|
||||
ToLog("Start TXWriteAccHash", 2);
|
||||
for(var num = 0; true; num++)
|
||||
{
|
||||
var Item = DApps.Smart.DBSmart.Read(num);
|
||||
if(!Item)
|
||||
break;
|
||||
var Body = BufLib.GetBufferFromObject(Item, DApps.Smart.FORMAT_ROW, 20000, {});
|
||||
DApps.Smart.DBSmartWrite(Item);
|
||||
}
|
||||
var Block = {BlockNum:MinimalValidBlock, SumHash:[]};
|
||||
var MaxAccount = DApps.Accounts.GetMaxAccount();
|
||||
var DataHash = DApps.Accounts.CalcHash(Block, MaxAccount);
|
||||
return DataHash;
|
||||
};
|
||||
global.TXWriteAccHash = TXWriteAccHash;
|
||||
global.EvalCode = function (Code)
|
||||
{
|
||||
var Result;
|
||||
|
@ -41,7 +41,7 @@ process.on('message', function (msg)
|
||||
case "ALive":
|
||||
break;
|
||||
case "Exit":
|
||||
process.exit(0);
|
||||
Exit();
|
||||
break;
|
||||
case "call":
|
||||
var Err = 0;
|
||||
@ -103,6 +103,19 @@ process.on('message', function (msg)
|
||||
}
|
||||
}
|
||||
});
|
||||
var RedirectServer;
|
||||
var HostingServer;
|
||||
|
||||
function Exit()
|
||||
{
|
||||
ToLogWeb("=Exit1=");
|
||||
if(RedirectServer)
|
||||
RedirectServer.close();
|
||||
if(HostingServer)
|
||||
HostingServer.close();
|
||||
ToLogWeb("=Exit2=");
|
||||
process.exit(0);
|
||||
};
|
||||
|
||||
function CheckAlive()
|
||||
{
|
||||
@ -111,8 +124,7 @@ function CheckAlive()
|
||||
var Delta = Date.now() - LastAlive;
|
||||
if(Delta > CHECK_STOP_CHILD_PROCESS)
|
||||
{
|
||||
ToLog("HOSTING: ALIVE TIMEOUT Stop and exit: " + Delta + "/" + global.CHECK_STOP_CHILD_PROCESS, 0);
|
||||
process.exit(0);
|
||||
Exit();
|
||||
return ;
|
||||
}
|
||||
};
|
||||
@ -144,7 +156,6 @@ require("../core/html-server");
|
||||
require("../core/transaction-validator");
|
||||
global.STAT_MODE = 1;
|
||||
setInterval(PrepareStatEverySecond, 1000);
|
||||
var HostingServer;
|
||||
if(global.HTTPS_HOSTING_DOMAIN)
|
||||
{
|
||||
var file_sert = GetDataPath("sertif.lst");
|
||||
@ -152,15 +163,20 @@ if(global.HTTPS_HOSTING_DOMAIN)
|
||||
var greenlock = require('greenlock').create({version:'draft-12', server:'https://acme-v02.api.letsencrypt.org/directory', configDir:GetDataPath('tmp'),
|
||||
});
|
||||
var redir = require('redirect-https')();
|
||||
require('http').createServer(greenlock.middleware(redir)).listen(80);
|
||||
RedirectServer = require('http').createServer(greenlock.middleware(redir));
|
||||
RedirectServer.on('error', function (err)
|
||||
{
|
||||
ToError('RedirectServer: ' + err.code);
|
||||
});
|
||||
RedirectServer.listen(80);
|
||||
var GetNewSert = 1;
|
||||
if(fs.existsSync(file_sert))
|
||||
{
|
||||
var certs = LoadParams(file_sert, {});
|
||||
var Delta = certs.expiresAt - Date.now();
|
||||
if(Delta > 7 * 86000 * 1000)
|
||||
if(Delta >= 10 * 24 * 3600 * 1000)
|
||||
{
|
||||
ToLog("USE OLD SERT. ExpiresAt: " + new Date(certs.expiresAt));
|
||||
ToLog("USE EXIST SERT. ExpiresAt: " + new Date(certs.expiresAt));
|
||||
GetNewSert = 0;
|
||||
var tlsOptions = {key:certs.privkey, cert:certs.cert + '\r\n' + certs.chain};
|
||||
HostingServer = require('https').createServer(tlsOptions, MainHTTPFunction);
|
||||
@ -191,12 +207,15 @@ else
|
||||
|
||||
function MainHTTPFunction(request,response)
|
||||
{
|
||||
if(!request.headers)
|
||||
return ;
|
||||
if(!request.socket || !request.socket.remoteAddress)
|
||||
return ;
|
||||
SetSafeResponce(response);
|
||||
var DataURL = url.parse(request.url);
|
||||
var Params = querystring.parse(DataURL.query);
|
||||
var Path = querystring.unescape(DataURL.pathname);
|
||||
ToLogWeb("Get Path:" + Path);
|
||||
var Type = request.method;
|
||||
if(Type === "POST")
|
||||
{
|
||||
@ -252,6 +271,7 @@ function RunListenServer()
|
||||
ToLogClient('Port ' + global.HTTP_HOSTING_PORT + ' in use, retrying...');
|
||||
if(HostingServer.Server)
|
||||
HostingServer.Server.close();
|
||||
if(!bWasRun)
|
||||
setTimeout(function ()
|
||||
{
|
||||
RunListenServer();
|
||||
@ -297,6 +317,7 @@ WalletFileMap["wallet.css"] = 1;
|
||||
WalletFileMap["history.html"] = 1;
|
||||
WalletFileMap["blockviewer.html"] = 1;
|
||||
WalletFileMap["web-wallet.html"] = 1;
|
||||
WalletFileMap["web-wallet-cn.html"] = 1;
|
||||
global.WebApi2 = {};
|
||||
global.HostingCaller = {};
|
||||
|
||||
@ -655,11 +676,11 @@ HostingCaller.DappSmartHTMLFile = function (Params)
|
||||
return {result:0};
|
||||
return HTTPCaller.DappSmartHTMLFile(Params);
|
||||
};
|
||||
HostingCaller.DappBlockFile = function (Params)
|
||||
HostingCaller.DappBlockFile = function (Params,responce)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
return HTTPCaller.DappBlockFile(Params);
|
||||
return HTTPCaller.DappBlockFile(Params, responce);
|
||||
};
|
||||
HostingCaller.DappInfo = function (Params)
|
||||
{
|
||||
@ -749,11 +770,11 @@ HostingCaller.DappTransactionList = function (Params)
|
||||
var arr = SERVER.GetTrRows(ParseNum(Params.BlockNum), ParseNum(Params.StartNum), ParseNum(Params.CountNum));
|
||||
return {arr:arr, result:1};
|
||||
};
|
||||
HostingCaller.DappStaticCall = function (Params)
|
||||
HostingCaller.DappStaticCall = function (Params,response)
|
||||
{
|
||||
if(typeof Params !== "object")
|
||||
return {result:0};
|
||||
return HTTPCaller.DappStaticCall(Params);
|
||||
return HTTPCaller.DappStaticCall(Params, response);
|
||||
};
|
||||
HostingCaller.GetHistoryTransactions = function (Params)
|
||||
{
|
||||
@ -792,12 +813,13 @@ setInterval(function ()
|
||||
setInterval(function ()
|
||||
{
|
||||
var MaxNumBlockDB = SERVER.GetMaxNumBlockDB();
|
||||
var arr = SERVER.GetStatBlockchain("POWER_BLOCKCHAIN", 100);
|
||||
var HASHARATE_BLOCK_LENGTH = 200;
|
||||
var arr = SERVER.GetStatBlockchain("POWER_BLOCKCHAIN", HASHARATE_BLOCK_LENGTH);
|
||||
if(arr.length)
|
||||
{
|
||||
var SumPow = 0;
|
||||
var Count = 0;
|
||||
for(var i = arr.length - 100; i < arr.length; i++)
|
||||
for(var i = arr.length - HASHARATE_BLOCK_LENGTH; i < arr.length; i++)
|
||||
if(arr[i])
|
||||
{
|
||||
SumPow += arr[i];
|
||||
@ -811,8 +833,7 @@ setInterval(function ()
|
||||
if(MaxNumBlockDB > Count)
|
||||
{
|
||||
var StartNum = MaxNumBlockDB - Count;
|
||||
var BufWrite = SERVER.BlockChainToBuf(StartNum, StartNum, MaxNumBlockDB);
|
||||
NodeBlockChain = BufWrite;
|
||||
NodeBlockChain = SERVER.BlockChainToBuf(StartNum, StartNum, MaxNumBlockDB);
|
||||
}
|
||||
}, 1000);
|
||||
require("./api-exchange.js");
|
||||
@ -823,3 +844,12 @@ try
|
||||
catch(e)
|
||||
{
|
||||
}
|
||||
global.LoadBlockFromNetwork = function (Params,F)
|
||||
{
|
||||
ToLog("RUN: LoadBlockFromNetwork:" + Params.BlockNum);
|
||||
process.RunRPC("LoadBlockFromNetwork", {BlockNum:Params.BlockNum, F:1}, function (Err,Block)
|
||||
{
|
||||
ToLog("RETURN: LoadBlockFromNetwork: " + Params.BlockNum);
|
||||
F(Err, Block);
|
||||
});
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user