tera/src/HTML/JS/terahashlib.js

412 lines
13 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 DELTA_LONG_MINING = 5000;
var BLOCKNUM_ALGO2 = 6560000;
var BLOCKNUM_HASH_NEW = 10195000;
var BLOCKNUM_TICKET_ALGO = 16070000;
if (typeof global === "object") {
global.GetHashFromSeqAddr = GetHashFromSeqAddr;
global.CalcHashBlockFromSeqAddr = CalcHashBlockFromSeqAddr;
global.GetHashFromNum2 = GetHashFromNum2;
global.GetHashFromNum3 = GetHashFromNum3;
global.GetHashFromArrNum2 = GetHashFromArrNum2;
global.XORArr = XORArr;
global.GetHash = GetHash;
if (global.LOCAL_RUN || global.TEST_NETWORK) {
BLOCKNUM_ALGO2 = 0;
if (global.TEST_NETWORK) {
BLOCKNUM_HASH_NEW = 100;
BLOCKNUM_TICKET_ALGO = 0;
}
else {
BLOCKNUM_HASH_NEW = 100;
BLOCKNUM_TICKET_ALGO = 0;
}
}
}
function GetHashFromSeqAddr(SeqHash, AddrHash, BlockNum, PrevHash, MiningVer) {
if (BlockNum < BLOCKNUM_ALGO2) {
var Hash = shaarrblock2(SeqHash, AddrHash, BlockNum);
return { Hash: Hash, PowHash: Hash, Hash1: Hash, Hash2: Hash };
}
var MinerID = ReadUintFromArr(AddrHash, 0);
var Nonce0 = ReadUintFromArr(AddrHash, 6);
var Nonce1 = ReadUintFromArr(AddrHash, 12);
var Nonce2 = ReadUintFromArr(AddrHash, 18);
var DeltaNum1 = ReadUint16FromArr(AddrHash, 24);
var DeltaNum2 = ReadUint16FromArr(AddrHash, 26);
var PrevHashNum;
if (PrevHash) {
PrevHashNum = ReadUint32FromArr(PrevHash, 28);
}
else {
PrevHashNum = ReadUint32FromArr(AddrHash, 28);
}
var Data = GetHash(SeqHash, PrevHashNum, BlockNum, MinerID, Nonce0, Nonce1, Nonce2, DeltaNum1, DeltaNum2);
if (MiningVer) {
if (AddrHash[17] !== MiningVer || AddrHash[23] !== MiningVer) {
Data.PowHash = [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];
}
}
return Data;
};
function GetHash(BlockHash, PrevHashNum, BlockNum, Miner, Nonce0, Nonce1, Nonce2, DeltaNum1, DeltaNum2) {
if (DeltaNum1 > DELTA_LONG_MINING)
DeltaNum1 = 0;
if (DeltaNum2 > DELTA_LONG_MINING)
DeltaNum2 = 0;
var HashBase = GetHashFromNum2(BlockNum, PrevHashNum);
var HashCurrent = GetHashFromArrNum2(BlockHash, Miner, Nonce0);
var HashNonce1 = GetHashFromNum3(BlockNum - DeltaNum1, Miner, Nonce1);
var HashNonce2 = GetHashFromNum3(BlockNum - DeltaNum2, Miner, Nonce2);
var Hash1 = XORArr(HashBase, HashNonce1);
var Hash2 = XORArr(HashCurrent, HashNonce2);
var Ret = { Hash: Hash2, Hash1: Hash1, Hash2: Hash2 };
if (CompareArr(Hash1, Hash2) > 0) {
Ret.PowHash = Hash1;
}
else {
Ret.PowHash = Hash2;
}
if (BlockNum >= BLOCKNUM_HASH_NEW) {
if (BlockNum >= BLOCKNUM_TICKET_ALGO)
Ret.Hash = sha3arr2(Hash1, Hash2);
else
Ret.Hash = shaarr2(Hash1, Hash2);
}
return Ret;
};
function CalcHashBlockFromSeqAddr(Block, PrevHash, MiningVer) {
var Value = GetHashFromSeqAddr(Block.SeqHash, Block.AddrHash, Block.BlockNum, PrevHash, MiningVer);
Block.Hash = Value.Hash;
Block.PowHash = Value.PowHash;
};
function XORArr(Arr1, Arr2) {
var Ret = [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];
for (var i = 0; i < 32; i++) {
Ret[i] = Arr1[i] ^ Arr2[i];
}
return Ret;
};
function GetHashFromNum2(Value1, Value2) {
var MeshArr = [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(MeshArr, Value1, 0);
WriteUintToArrOnPos(MeshArr, Value2, 6);
return sha3(MeshArr);
};
function GetHashFromArrNum2(Arr, Value1, Value2) {
var MeshArr = [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, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0];
WriteArrToArrOnPos(MeshArr, Arr, 0, 32);
WriteUintToArrOnPos(MeshArr, Value1, 32);
WriteUintToArrOnPos(MeshArr, Value2, 38);
return sha3(MeshArr);
};
function GetHashFromNum3(Value1, Value2, Value3) {
var MeshArr = [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(MeshArr, Value1, 0);
WriteUintToArrOnPos(MeshArr, Value2, 6);
WriteUintToArrOnPos(MeshArr, Value3, 12);
return sha3(MeshArr);
};
function ReadUintFromArr(arr, len) {
if (len === undefined) {
len = arr.len;
arr.len += 6;
}
var value = (arr[len + 5] << 23) * 2 + (arr[len + 4] << 16) + (arr[len + 3] << 8) + arr[len + 2];
value = value * 256 + arr[len + 1];
value = value * 256 + arr[len];
return value;
};
function ReadUint32FromArr(arr, len) {
if (len === undefined) {
len = arr.len;
arr.len += 4;
}
var value = (arr[len + 3] << 23) * 2 + (arr[len + 2] << 16) + (arr[len + 1] << 8) + arr[len];
return value;
};
function ReadUint16FromArr(arr, len) {
if (len === undefined) {
len = arr.len;
arr.len += 2;
}
var value = (arr[len + 1] << 8) + arr[len];
return value;
};
function ReadArrFromArr(arr, length) {
var Ret = [];
var len = arr.len;
for (var i = 0; i < length; i++) {
Ret[i] = arr[len + i];
}
arr.len += length;
return Ret;
};
function WriteUintToArr(arr, Num) {
var len = arr.length;
arr[len] = Num & 0xFF;
arr[len + 1] = (Num >>> 8) & 0xFF;
arr[len + 2] = (Num >>> 16) & 0xFF;
arr[len + 3] = (Num >>> 24) & 0xFF;
var NumH = Math.floor(Num / 4294967296);
arr[len + 4] = NumH & 0xFF;
arr[len + 5] = (NumH >>> 8) & 0xFF;
};
function WriteUintToArrOnPos(arr, Num, Pos) {
arr[Pos] = Num & 0xFF;
arr[Pos + 1] = (Num >>> 8) & 0xFF;
arr[Pos + 2] = (Num >>> 16) & 0xFF;
arr[Pos + 3] = (Num >>> 24) & 0xFF;
var NumH = Math.floor(Num / 4294967296);
arr[Pos + 4] = NumH & 0xFF;
arr[Pos + 5] = (NumH >>> 8) & 0xFF;
};
function WriteUint32ToArr(arr, Num) {
var len = arr.length;
arr[len] = Num & 0xFF;
arr[len + 1] = (Num >>> 8) & 0xFF;
arr[len + 2] = (Num >>> 16) & 0xFF;
arr[len + 3] = (Num >>> 24) & 0xFF;
};
function WriteUint32ToArrOnPos(arr, Num, Pos) {
arr[Pos] = Num & 0xFF;
arr[Pos + 1] = (Num >>> 8) & 0xFF;
arr[Pos + 2] = (Num >>> 16) & 0xFF;
arr[Pos + 3] = (Num >>> 24) & 0xFF;
};
function WriteUint16ToArrOnPos(arr, Num, Pos) {
arr[Pos] = Num & 0xFF;
arr[Pos + 1] = (Num >>> 8) & 0xFF;
};
function WriteArrToArr(arr, arr2, ConstLength) {
var len = arr.length;
for (var i = 0; i < ConstLength; i++) {
arr[len + i] = arr2[i];
}
};
function WriteArrToArrOnPos(arr, arr2, Pos, ConstLength) {
for (var i = 0; i < ConstLength; i++) {
arr[Pos + i] = arr2[i];
}
};
function WriteArrToArrHOnPos(arr, arr2, Pos, ConstLength) {
for (var i = 0; i < ConstLength; i++) {
arr[Pos + i] |= (arr2[i] << 8);
}
};
function ConvertBufferToStr(Data) {
for (var key in Data) {
var item = Data[key];
if (item instanceof Buffer) {
Data[key] = GetHexFromArr(item);
}
else
if (typeof item === "object")
ConvertBufferToStr(item);
}
};
function CopyObjValue(obj, num) {
if (num && num > 5)
return obj;
var ret = {};
for (var key in obj) {
var val = obj[key];
if ((typeof val === "object") && !(val instanceof Buffer) && !(val instanceof ArrayBuffer) && !(val instanceof Array))
val = CopyObjValue(val, num + 1);
ret[key] = val;
}
return ret;
};
function CopyArr(arr1) {
var arr2 = [];
if (arr1)
for (var i = 0, len = arr1.length; i < len; i++)
arr2[i] = arr1[i];
return arr2;
};
function ParseNum(a) {
var Num = parseInt(a);
if (!Num)
Num = 0;
if (isNaN(Num))
Num = 0;
if (Num < 0)
Num = 0;
return Num;
};
function CompareArr(a, b) {
for (var i = 0, len = a.length; i < len; i++) {
if (a[i] !== b[i])
return a[i] - b[i];
}
return 0;
};
function CompareArrL(a, b) {
if (a.length !== b.length)
return a.length - b.length;
for (var i = 0, len = a.length; i < len; i++) {
if (a[i] !== b[i])
return a[i] - b[i];
}
return 0;
};
function GetSeqHash(BlockNum, PrevHash, TreeHash) {
var arr = [GetArrFromValue(BlockNum), PrevHash, TreeHash];
var SeqHash = CalcHashFromArray(arr, true);
return SeqHash;
};
function arr2(Value1, Value2) {
var Buf = [];
for (var n = 0, len = Value1.length; n < len; n++)
Buf.push(Value1[n]);
for (var n = 0, len = Value2.length; n < len; n++)
Buf.push(Value2[n]);
return Buf;
};
function shaarr2(Value1, Value2) {
return shaarr(arr2(Value1, Value2));
};
function sha3arr2(Value1, Value2) {
return sha3(arr2(Value1, Value2));
};
function GetBlockArrFromBuffer(BufRead, Info) {
if (!BufRead || BufRead.length < 10)
return [];
var BLOCK_PROCESSING_LENGTH = 8;
var BLOCK_PROCESSING_LENGTH2 = BLOCK_PROCESSING_LENGTH * 2;
BufRead.len = 0;
var StartNum = ReadUintFromArr(BufRead);
var CountLoad = ReadUint32FromArr(BufRead);
var BufSize = 6 + 4 + BLOCK_PROCESSING_LENGTH2 * 32 + 32 + 6 + CountLoad * 64;
if (CountLoad <= 0 || BufSize !== BufRead.length) {
return [];
}
var PrevBlock;
var BlockArr = [];
for (var i = 0; i < CountLoad + BLOCK_PROCESSING_LENGTH2; i++) {
var Block = {};
Block.BlockNum = StartNum + i;
if (i < BLOCK_PROCESSING_LENGTH2) {
Block.Hash = ReadArrFromArr(BufRead, 32);
}
else {
if (i === BLOCK_PROCESSING_LENGTH2) {
Block.SumHash = ReadArrFromArr(BufRead, 32);
Block.SumPow = ReadUintFromArr(BufRead);
}
Block.TreeHash = ReadArrFromArr(BufRead, 32);
Block.AddrHash = ReadArrFromArr(BufRead, 32);
var arr = [];
var start = i - BLOCK_PROCESSING_LENGTH2;
for (var n = 0; n < BLOCK_PROCESSING_LENGTH; n++) {
var Prev = BlockArr[start + n];
arr.push(Prev.Hash);
}
Block.PrevHash = CalcHashFromArray(arr, true);
Block.SeqHash = GetSeqHash(Block.BlockNum, Block.PrevHash, Block.TreeHash);
var PrevHashNum = ReadUint32FromArr(Block.PrevHash, 28);
var PrevAddrNum = ReadUint32FromArr(Block.AddrHash, 28);
if (PrevHashNum !== PrevAddrNum && Block.BlockNum > 20000000) {
if (global.WATCHDOG_DEV) {
var Str = "";
if (Info && Info.Node)
Str = " from " + NodeName(Info.Node);
ToError("Error on block load: " + Block.BlockNum + Str);
}
return [];
}
CalcHashBlockFromSeqAddr(Block, Block.PrevHash);
Block.Power = GetPowPower(Block.PowHash);
if (PrevBlock) {
Block.SumHash = shaarr2(PrevBlock.SumHash, Block.Hash);
}
PrevBlock = Block;
}
Block.TrCount = 0;
Block.TrDataPos = 0;
Block.TrDataLen = 0;
BlockArr.push(Block);
}
for (var i = BlockArr.length - 1; i >= 0; i--) {
var Block = BlockArr[i];
if (!Block.SumHash) {
BlockArr = BlockArr.slice(i + 1);
break;
}
}
return BlockArr;
};
function shaarrblock2(Value1, Value2, BlockNum) {
return shaarrblock(arr2(Value1, Value2), BlockNum);
};
if (typeof global === "object") {
global.ReadUint32FromArr = ReadUint32FromArr;
global.ReadUintFromArr = ReadUintFromArr;
global.ReadUint16FromArr = ReadUint16FromArr;
global.WriteUintToArr = WriteUintToArr;
global.WriteUint32ToArr = WriteUint32ToArr;
global.WriteUint32ToArrOnPos = WriteUint32ToArrOnPos;
global.WriteUint16ToArrOnPos = WriteUint16ToArrOnPos;
global.WriteUintToArrOnPos = WriteUintToArrOnPos;
global.WriteArrToArr = WriteArrToArr;
global.WriteArrToArrOnPos = WriteArrToArrOnPos;
global.WriteArrToArrHOnPos = WriteArrToArrHOnPos;
global.ConvertBufferToStr = ConvertBufferToStr;
global.CopyObjValue = CopyObjValue;
global.CopyArr = CopyArr;
global.ParseNum = ParseNum;
global.CompareArr = CompareArr;
global.CompareArrL = CompareArrL;
global.shaarr2 = shaarr2;
global.sha3arr2 = sha3arr2;
global.arr2 = arr2;
global.GetBlockArrFromBuffer = GetBlockArrFromBuffer;
global.shaarrblock2 = shaarrblock2;
}
else
if (typeof window === "object") {
global = window;
}