/* * @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; var 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 = global.ReadUint32FromArr(Block.PrevHash, 28); var Ret = global.GetHash(Block.SeqHash, PrevHashNum, Block.BlockNum, MinerID, 0, 0, 0, 0, 0); Block.Hash = Ret.Hash; Block.PowHash = Ret.PowHash; Block.Power = global.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]; global.WriteUintToArrOnPos(Block.AddrHash, MinerID, 0); global.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; global.ToLog("WAS ALLOC MEMORY ERROR. NEW TRY: " + MAX_MEMORY3); BufferNonce3 = new Uint32Array(MAX_MEMORY3); BufferBlockNum3 = new Uint32Array(MAX_MEMORY3); } bWasInitVerOK3 = 1; global.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 = global.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 = global.ReadUint32FromArr(Block.PrevHash, 28); var HashBase = global.GetHashFromNum2(BlockNum, PrevHashNum); var Value1 = FindHashBuffer3(HashBase, BlockNum, Miner, 1); if (Value1) { var Hash1 = global.XORArr(HashBase, Value1.Hash); if (global.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 = global.GetHashFromArrNum2(Block.SeqHash, Miner, Nonce0); var Value2 = FindHashBuffer3(HashCurrent, BlockNum, Miner, 1); if (Value2) { var Hash2 = global.XORArr(HashCurrent, Value2.Hash); if (global.CompareArr(MaxLider.Hash2, Hash2) > 0) { MaxLider.Nonce0 = Nonce0; MaxLider.Hash2 = Hash2; MaxLider.Nonce2 = Value2.Nonce; MaxLider.DeltaNum2 = Value2.DeltaNum; Ret = 1; if (global.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]; global.WriteUintToArrOnPos(Block.AddrHash, Miner, 0); global.WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce0, 6); global.WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce1, 12); global.WriteUintToArrOnPos(Block.AddrHash, MaxLider.Nonce2, 18); global.WriteUint16ToArrOnPos(Block.AddrHash, MaxLider.DeltaNum1, 24); global.WriteUint16ToArrOnPos(Block.AddrHash, MaxLider.DeltaNum2, 26); global.WriteUint32ToArrOnPos(Block.AddrHash, PrevHashNum, 28); Block.Hash = MaxLider.Hash2; if (global.CompareArr(MaxLider.Hash1, MaxLider.Hash2) > 0) { Block.PowHash = MaxLider.Hash1; } else { Block.PowHash = MaxLider.Hash2; } if (BlockNum >= global.BLOCKNUM_TICKET_ALGO) Block.Hash = global.sha3arr2(MaxLider.Hash1, MaxLider.Hash2); else Block.Hash = global.shaarr2(MaxLider.Hash1, MaxLider.Hash2); var Power = global.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 = global.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 = global.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 }; };