228 lines
7.6 KiB
JavaScript
228 lines
7.6 KiB
JavaScript
|
/*
|
||
|
* @project: TERA
|
||
|
* @version: Development (beta)
|
||
|
* @license: MIT (not for evil)
|
||
|
* @copyright: Yuriy Ivanov (Vtools) 2017-2019 [progr76@gmail.com]
|
||
|
* Web: https://terafoundation.org
|
||
|
* Twitter: https://twitter.com/terafoundation
|
||
|
* Telegram: https://t.me/terafoundation
|
||
|
*/
|
||
|
|
||
|
var START_NONCE = 0;
|
||
|
const COUNT_FIND_HASH1 = 64;
|
||
|
const DELTA_LONG_MINING = 5000;
|
||
|
var BLOCKNUM_ALGO2 = 6560000;
|
||
|
if(global.LOCAL_RUN || global.TEST_NETWORK)
|
||
|
{
|
||
|
BLOCKNUM_ALGO2 = 0;
|
||
|
}
|
||
|
require('./library.js');
|
||
|
require('./crypto-library.js');
|
||
|
require('../HTML/JS/terahashlib.js');
|
||
|
var DELTA_NONCE = Math.pow(2, 40) * global.MINING_VERSION_NUM;
|
||
|
global.CreateHashMinimal = CreateHashMinimal;
|
||
|
global.CreatePOWVersionX = CreatePOWVersion3;
|
||
|
|
||
|
function CreateHashMinimal(Block,MinerID)
|
||
|
{
|
||
|
if(Block.BlockNum < BLOCKNUM_ALGO2)
|
||
|
{
|
||
|
throw "BlockNum < BLOCKNUM_ALGO2";
|
||
|
return false;
|
||
|
}
|
||
|
var PrevHashNum = ReadUint32FromArr(Block.PrevHash, 28);
|
||
|
var Ret = GetHash(Block.SeqHash, PrevHashNum, Block.BlockNum, MinerID, 0, 0, 0, 0, 0);
|
||
|
Block.Hash = Ret.Hash;
|
||
|
Block.PowHash = Ret.PowHash;
|
||
|
Block.Power = GetPowPower(Block.PowHash);
|
||
|
Block.AddrHash = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||
|
WriteUintToArrOnPos(Block.AddrHash, MinerID, 0);
|
||
|
WriteUint32ToArrOnPos(Block.AddrHash, PrevHashNum, 28);
|
||
|
return true;
|
||
|
};
|
||
|
var MAX_MEMORY3 = 0, SHIFT_MASKA3;
|
||
|
var BufferNonce3, BufferBlockNum3;
|
||
|
var bWasInitVer3, bWasInitVerOK3;
|
||
|
|
||
|
function InitVer3(Block)
|
||
|
{
|
||
|
bWasInitVer3 = 1;
|
||
|
if(Block.ProcessMemorySize > 0)
|
||
|
{
|
||
|
var MAXARRAYSIZE = (1 << 30) * 2 - 1;
|
||
|
var MaxArrCount = Math.min(Math.trunc(Block.ProcessMemorySize / 8), MAXARRAYSIZE);
|
||
|
var BitCount = 0;
|
||
|
MAX_MEMORY3 = 1;
|
||
|
for(var b = 0; b < 32; b++)
|
||
|
{
|
||
|
if(MAX_MEMORY3 > MaxArrCount)
|
||
|
{
|
||
|
BitCount--;
|
||
|
MAX_MEMORY3 = MAX_MEMORY3 / 2;
|
||
|
break;
|
||
|
}
|
||
|
BitCount++;
|
||
|
MAX_MEMORY3 = MAX_MEMORY3 * 2;
|
||
|
}
|
||
|
SHIFT_MASKA3 = 32 - BitCount;
|
||
|
try
|
||
|
{
|
||
|
BufferNonce3 = new Uint32Array(MAX_MEMORY3);
|
||
|
BufferBlockNum3 = new Uint32Array(MAX_MEMORY3);
|
||
|
}
|
||
|
catch(e)
|
||
|
{
|
||
|
SHIFT_MASKA3 = SHIFT_MASKA3 + 1;
|
||
|
MAX_MEMORY3 = MAX_MEMORY3 / 2;
|
||
|
ToLog("WAS ALLOC MEMORY ERROR. NEW TRY: " + MAX_MEMORY3);
|
||
|
BufferNonce3 = new Uint32Array(MAX_MEMORY3);
|
||
|
BufferBlockNum3 = new Uint32Array(MAX_MEMORY3);
|
||
|
}
|
||
|
bWasInitVerOK3 = 1;
|
||
|
ToLog("MAX HASH ITEMS=" + Math.trunc(MAX_MEMORY3 / 1024 / 1024) + " M");
|
||
|
}
|
||
|
};
|
||
|
|
||
|
function CreatePOWVersion3(Block,bHashPump)
|
||
|
{
|
||
|
if(!bWasInitVer3)
|
||
|
InitVer3(Block);
|
||
|
if(!bWasInitVerOK3)
|
||
|
return 0;
|
||
|
if(!Block.LastNonce)
|
||
|
Block.LastNonce = 0;
|
||
|
if(!Block.HashCount)
|
||
|
Block.HashCount = 0;
|
||
|
if(!Block.LastNonce0)
|
||
|
Block.LastNonce0 = 0;
|
||
|
if(!Block.MaxLider)
|
||
|
{
|
||
|
Block.HashCount = 0;
|
||
|
Block.MaxLider = {Nonce0:0, Nonce1:0, Nonce2:0, DeltaNum1:0, DeltaNum2:0, Hash1:[255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255], Hash2:[255,
|
||
|
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
|
||
|
255, 255, 255, 255, 255, 255], };
|
||
|
}
|
||
|
var MaxLider = Block.MaxLider;
|
||
|
var RunCount = Block.RunCount;
|
||
|
var BlockNum = Block.BlockNum;
|
||
|
var Miner = Block.MinerID;
|
||
|
var StartNonceRnd = DELTA_NONCE + Block.LastNonce + Math.trunc(3000000000 * Math.random());
|
||
|
var List = GetNonceHashArr(BlockNum, Miner, StartNonceRnd, RunCount);
|
||
|
for(var n = 0; n < RunCount; n++)
|
||
|
{
|
||
|
var Nonce = List.ArrNonce[n];
|
||
|
var HashNum = List.ArrHash[n] >>> SHIFT_MASKA3;
|
||
|
BufferNonce3[HashNum] = Nonce;
|
||
|
BufferBlockNum3[HashNum] = BlockNum;
|
||
|
}
|
||
|
Block.LastNonce += RunCount;
|
||
|
if(bHashPump)
|
||
|
return ;
|
||
|
var Ret = 0;
|
||
|
var PrevHashNum = ReadUint32FromArr(Block.PrevHash, 28);
|
||
|
var HashBase = GetHashFromNum2(BlockNum, PrevHashNum);
|
||
|
var Value1 = FindHashBuffer3(HashBase, BlockNum, Miner, 1);
|
||
|
if(Value1)
|
||
|
{
|
||
|
var Hash1 = XORArr(HashBase, Value1.Hash);
|
||
|
if(CompareArr(MaxLider.Hash1, Hash1) > 0)
|
||
|
{
|
||
|
MaxLider.Hash1 = Hash1;
|
||
|
MaxLider.Nonce1 = Value1.Nonce;
|
||
|
MaxLider.DeltaNum1 = Value1.DeltaNum;
|
||
|
Ret = 1;
|
||
|
}
|
||
|
}
|
||
|
START_NONCE = Block.LastNonce0;
|
||
|
var CountEnd = START_NONCE + 50000;
|
||
|
var Nonce0;
|
||
|
for(Nonce0 = START_NONCE; Nonce0 < CountEnd; Nonce0++)
|
||
|
{
|
||
|
var HashCurrent = GetHashFromArrNum2(Block.SeqHash, Miner, Nonce0);
|
||
|
var Value2 = FindHashBuffer3(HashCurrent, BlockNum, Miner, 1);
|
||
|
if(Value2)
|
||
|
{
|
||
|
var Hash2 = XORArr(HashCurrent, Value2.Hash);
|
||
|
if(CompareArr(MaxLider.Hash2, Hash2) > 0)
|
||
|
{
|
||
|
MaxLider.Nonce0 = Nonce0;
|
||
|
MaxLider.Hash2 = Hash2;
|
||
|
MaxLider.Nonce2 = Value2.Nonce;
|
||
|
MaxLider.DeltaNum2 = Value2.DeltaNum;
|
||
|
Ret = 1;
|
||
|
if(CompareArr(MaxLider.Hash1, Hash2) > 0)
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
Block.LastNonce0 = Nonce0;
|
||
|
if(Ret)
|
||
|
{
|
||
|
Block.AddrHash = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||
|
WriteUintToArrOnPos(Block.AddrHash, Miner, 0);
|
||
|
WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce0, 6);
|
||
|
WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce1, 12);
|
||
|
WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce2, 18);
|
||
|
WriteUint16ToArrOnPos(Block.AddrHash, MaxLider.DeltaNum1, 24);
|
||
|
WriteUint16ToArrOnPos(Block.AddrHash, MaxLider.DeltaNum2, 26);
|
||
|
WriteUint32ToArrOnPos(Block.AddrHash, PrevHashNum, 28);
|
||
|
Block.Hash = MaxLider.Hash2;
|
||
|
if(CompareArr(MaxLider.Hash1, MaxLider.Hash2) > 0)
|
||
|
{
|
||
|
Block.PowHash = MaxLider.Hash1;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
Block.PowHash = MaxLider.Hash2;
|
||
|
}
|
||
|
if(BlockNum >= global.BLOCKNUM_TICKET_ALGO)
|
||
|
Block.Hash = sha3arr2(MaxLider.Hash1, MaxLider.Hash2);
|
||
|
else
|
||
|
Block.Hash = shaarr2(MaxLider.Hash1, MaxLider.Hash2);
|
||
|
var Power = GetPowPower(Block.PowHash);
|
||
|
Block.HashCount = (1 << Power) >>> 0;
|
||
|
}
|
||
|
return Ret;
|
||
|
};
|
||
|
|
||
|
function FindHashBuffer3(HashFind,BlockNum,Miner,CountFind)
|
||
|
{
|
||
|
var HashNum = ReadIndexFromArr(HashFind);
|
||
|
for(var i = 0; i < CountFind; i++)
|
||
|
{
|
||
|
var Index = HashNum ^ i;
|
||
|
var BlockNum2 = BufferBlockNum3[Index];
|
||
|
if(BlockNum2 && BlockNum2 > BlockNum - DELTA_LONG_MINING)
|
||
|
{
|
||
|
var Nonce2 = DELTA_NONCE + BufferNonce3[Index];
|
||
|
var Hash2 = GetHashFromNum3(BlockNum2, Miner, Nonce2);
|
||
|
return {Hash:Hash2, DeltaNum:BlockNum - BlockNum2, Nonce:Nonce2};
|
||
|
}
|
||
|
}
|
||
|
return undefined;
|
||
|
};
|
||
|
|
||
|
function ReadIndexFromArr(arr)
|
||
|
{
|
||
|
var value = (arr[0] << 23) * 2 + (arr[1] << 16) + (arr[2] << 8) + arr[3];
|
||
|
value = value >>> SHIFT_MASKA3;
|
||
|
return value;
|
||
|
};
|
||
|
global.GetNonceHashArr = function (BlockNum,Miner,StartNonceRnd,CountNonce)
|
||
|
{
|
||
|
var ArrNonce = [];
|
||
|
var ArrHash = [];
|
||
|
for(var n = 0; n < CountNonce; n++)
|
||
|
{
|
||
|
var Nonce = StartNonceRnd + n;
|
||
|
var HashNonce = GetHashFromNum3(BlockNum, Miner, Nonce);
|
||
|
var HashNum = (HashNonce[0] << 23) * 2 + (HashNonce[1] << 16) + (HashNonce[2] << 8) + HashNonce[3];
|
||
|
ArrNonce[n] = Nonce;
|
||
|
ArrHash[n] = HashNum;
|
||
|
}
|
||
|
return {ArrNonce:ArrNonce, ArrHash:ArrHash};
|
||
|
};
|