2019-02-10 19:53:54 +00:00
/ *
* @ project : TERA
* @ version : Development ( beta )
* @ license : MIT ( not for evil )
2019-03-16 16:08:05 +00:00
* @ copyright : Yuriy Ivanov ( Vtools ) 2017 - 2019 [ progr76 @ gmail . com ]
2019-02-10 19:53:54 +00:00
* Web : https : //terafoundation.org
* Twitter : https : //twitter.com/terafoundation
* Telegram : https : //web.telegram.org/#/im?p=@terafoundation
* /
global . PROCESS _NAME = "STATIC" ;
const crypto = require ( 'crypto' ) ;
const fs = require ( 'fs' ) ;
require ( "../core/constant" ) ;
2019-04-05 10:13:44 +00:00
require ( '../core/block-loader-const' ) ;
require ( '../core/rest_tables.js' ) ;
require ( '../dapp/accounts.js' ) ;
require ( '../dapp/smart.js' ) ;
2019-02-10 19:53:54 +00:00
global . DATA _PATH = GetNormalPathString ( global . DATA _PATH ) ;
global . CODE _PATH = GetNormalPathString ( global . CODE _PATH ) ;
require ( "../core/library" ) ;
global . READ _ONLY _DB = 1 ;
var LastAlive = Date . now ( ) ;
setTimeout ( function ( )
{
setInterval ( CheckAlive , 1000 ) ;
} , 20000 ) ;
setInterval ( function ( )
{
process . send ( { cmd : "Alive" } ) ;
} , 1000 ) ;
process . send ( { cmd : "online" , message : "OK" } ) ;
process . on ( 'message' , function ( msg )
{
LastAlive = Date . now ( ) ;
switch ( msg . cmd )
{
case "ALive" :
break ;
case "Exit" :
process . exit ( 0 ) ;
break ;
case "call" :
var Err = 0 ;
var Ret ;
try
{
Ret = global [ msg . Name ] ( msg . Params ) ;
}
catch ( e )
{
Err = 1 ;
Ret = "" + e ;
}
if ( msg . id )
process . send ( { cmd : "retcall" , id : msg . id , Err : Err , Params : Ret } ) ;
break ;
case "GETBLOCKHEADER" :
GETBLOCKHEADER ( msg ) ;
break ;
case "GETBLOCK" :
GETBLOCK ( msg ) ;
break ;
case "GETCODE" :
GETCODE ( msg ) ;
break ;
2019-03-18 15:36:08 +00:00
case "GETREST" :
GETREST ( msg ) ;
break ;
2019-04-05 10:13:44 +00:00
case "GETSMART" :
GETSMART ( msg ) ;
break ;
2019-02-10 19:53:54 +00:00
}
} ) ;
function CheckAlive ( )
{
if ( global . NOALIVE )
return ;
var Delta = Date . now ( ) - LastAlive ;
if ( Delta > CHECK _STOP _CHILD _PROCESS )
{
2019-02-26 01:55:33 +00:00
ToLog ( "STATIC-DB: ALIVE TIMEOUT Stop and exit: " + Delta + "/" + global . CHECK _STOP _CHILD _PROCESS ) ;
2019-02-10 19:53:54 +00:00
process . exit ( 0 ) ;
return ;
}
} ;
process . on ( 'uncaughtException' , function ( err )
{
ToError ( err . stack ) ;
ToLog ( err . stack ) ;
2019-02-26 01:55:33 +00:00
TO _ERROR _LOG ( "STATIC-DB" , 777 , err ) ;
ToLog ( "-----------------STATIC-DB EXIT------------------" ) ;
2019-02-10 19:53:54 +00:00
process . exit ( ) ;
} ) ;
process . on ( 'error' , function ( err )
{
2019-02-26 01:55:33 +00:00
ToError ( "STATIC-DB:\n" + err . stack ) ;
2019-02-10 19:53:54 +00:00
ToLog ( err . stack ) ;
} ) ;
var CServerDB = require ( "../core/db/block-db" ) ;
var KeyPair = crypto . createECDH ( 'secp256k1' ) ;
KeyPair . setPrivateKey ( Buffer . from ( [ 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 ,
77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 , 77 ] ) ) ;
global . SERVER = new CServerDB ( KeyPair , undefined , undefined , false , true ) ;
global . HTTP _PORT _NUMBER = 0 ;
setInterval ( function ( )
{
if ( SERVER )
SERVER . ClearBufMap ( ) ;
2019-04-05 10:13:44 +00:00
DApps . Accounts . Close ( ) ;
DApps . Smart . DBSmart . Close ( ) ;
2019-02-10 19:53:54 +00:00
global . BlockDB . CloseDBFile ( "block-header" ) ;
global . BlockDB . CloseDBFile ( "block-body" ) ;
} , 1000 ) ;
function GETBLOCKHEADER ( msg )
{
var Data = msg . Data ;
var StartNum = undefined ;
var BlockNum ;
var LoadHash = Data . Hash ;
var Foward = Data . Foward ;
if ( Foward )
{
var BlockDB = SERVER . ReadBlockHeaderDB ( Data . BlockNum ) ;
2019-04-05 10:13:44 +00:00
if ( BlockDB && BlockDB . SumHash && ( CompareArr ( BlockDB . SumHash , LoadHash ) === 0 || IsZeroArr ( LoadHash ) ) )
2019-02-10 19:53:54 +00:00
{
StartNum = Data . BlockNum - BLOCK _PROCESSING _LENGTH2 ;
if ( StartNum < 0 )
StartNum = 0 ;
BlockNum = StartNum + COUNT _BLOCKS _FOR _LOAD + BLOCK _PROCESSING _LENGTH2 ;
if ( BlockNum > SERVER . GetMaxNumBlockDB ( ) )
BlockNum = SERVER . GetMaxNumBlockDB ( ) ;
}
}
else
{
BlockNum = Data . BlockNum ;
var IsSum = Data . IsSum ;
var Count = Data . Count ;
if ( ! Count || Count < 0 || BlockNum < 0 )
return ;
if ( Count > COUNT _BLOCKS _FOR _LOAD )
Count = COUNT _BLOCKS _FOR _LOAD ;
Count += BLOCK _PROCESSING _LENGTH2 ;
var BlockDB = SERVER . ReadBlockHeaderDB ( BlockNum ) ;
if ( BlockDB && ( BlockDB . Prepared && ( ! IsSum ) && BlockDB . Hash && CompareArr ( BlockDB . Hash , LoadHash ) === 0 || BlockDB . bSave && IsSum && BlockDB . SumHash && CompareArr ( BlockDB . SumHash ,
LoadHash ) === 0 ) )
{
StartNum = BlockNum - Count + 1 ;
if ( StartNum < 0 )
StartNum = 0 ;
}
}
var BufWrite = SERVER . BlockChainToBuf ( StartNum , StartNum , BlockNum ) ;
process . send ( { cmd : "Send" , addrStr : msg . addrStr , Method : "RETBLOCKHEADER" , Context : msg . Context , Data : BufWrite } ) ;
} ;
function GETBLOCK ( msg )
{
var Data = msg . Data ;
var BlockNum = Data . BlockNum ;
var TreeHash = Data . TreeHash ;
if ( msg . Context . SendCount )
{
return ;
}
var BufWrite ;
2019-04-05 10:13:44 +00:00
var BlockDB = SERVER . ReadBlockDB ( BlockNum ) ;
2019-02-10 19:53:54 +00:00
var StrSend ;
2019-04-05 10:13:44 +00:00
if ( BlockDB && ( CompareArr ( BlockDB . TreeHash , TreeHash ) === 0 || IsZeroArr ( TreeHash ) ) )
2019-02-10 19:53:54 +00:00
{
2019-04-05 10:13:44 +00:00
var BufWrite = BufLib . GetBufferFromObject ( BlockDB , FORMAT _BLOCK _TRANSFER , MAX _PACKET _LENGTH , WRK _BLOCK _TRANSFER ) ;
2019-02-10 19:53:54 +00:00
StrSend = "OK" ;
var TreeHashTest = CalcTreeHashFromArrBody ( BlockDB . BlockNum , BlockDB . arrContent ) ;
if ( CompareArr ( BlockDB . TreeHash , TreeHashTest ) !== 0 )
{
ToLog ( "1. BAD CMP TreeHash block=" + BlockNum + " TO: " + msg . addrStr . substr ( 0 , 8 ) + " TreeHashTest=" + GetHexFromArr ( TreeHashTest ) + " DB TreeHash=" + GetHexFromArr ( BlockDB . TreeHash ) ) ;
StrSend = "NO" ;
}
}
if ( StrSend === "OK" )
{
ADD _TO _STAT ( "BLOCK_SEND" ) ;
}
else
{
BufWrite = BufLib . GetNewBuffer ( 100 ) ;
StrSend = "NO" ;
}
process . send ( { cmd : "Send" , addrStr : msg . addrStr , Method : "RETGETBLOCK" , Context : msg . Context , Data : BufWrite } ) ;
} ;
function GETCODE ( msg )
{
var VersionNum = msg . Data ;
var fname = GetDataPath ( "Update/wallet-" + VersionNum + ".zip" ) ;
if ( fs . existsSync ( fname ) )
{
var data = fs . readFileSync ( fname ) ;
process . send ( { cmd : "Send" , addrStr : msg . addrStr , Method : "RETCODE" , Context : msg . Context , Data : data } ) ;
}
} ;
2019-03-18 15:36:08 +00:00
function GETREST ( msg )
{
2019-04-05 10:13:44 +00:00
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 } ) ;
2019-03-18 15:36:08 +00:00
} ;