SHA256
back32hash 5591: готово к тестам
Вроде как всё готово к тестам.
This commit is contained in:
@@ -1097,9 +1097,12 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
const BLOCK_TYPE_SESSIONS = 50;
|
||||
const BLOCK_TYPE_TRUSTED_STATE = 70;
|
||||
const BLOCK_TYPE_ARCHIVE_HEAD = 80;
|
||||
const BCH_FRAME_HEADER_SIZE = 56;
|
||||
const BCH_FRAME_HEADER_SIZE = 88;
|
||||
const BCH_FRAME_CODE_V1 = 0x0001;
|
||||
const SHINE_ARWEAVE_APP_TAG = 'test5590';
|
||||
// Transport namespace актуального standalone Viewer.
|
||||
const SHINE_PROTOCOL_NAMESPACE = 'test5591';
|
||||
const SHINE_ARWEAVE_APP_TAG = SHINE_PROTOCOL_NAMESPACE;
|
||||
const SHINE_ARWEAVE_CHANNEL_TAG = 'c';
|
||||
const BCH_TYPE_TECH = 0;
|
||||
const BCH_TYPE_TEXT = 1;
|
||||
const BCH_SUBTYPE_HEADER = 0;
|
||||
@@ -2058,22 +2061,23 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
if (frameCode !== BCH_FRAME_CODE_V1) {
|
||||
throw new Error(`Неожиданный frameCode 0x${frameCode.toString(16)} (ожидался 0x0001)`);
|
||||
}
|
||||
const blockSize = readInt32BE(bytes, 34);
|
||||
const blockSize = readInt32BE(bytes, 66);
|
||||
if (blockSize !== bytes.length || blockSize < BCH_FRAME_HEADER_SIZE) {
|
||||
throw new Error(`Frame size mismatch: blockSize=${blockSize}, actual=${bytes.length}`);
|
||||
}
|
||||
const hashBytes = await digestSha256(bytes);
|
||||
const type = readUint16BE(bytes, 50);
|
||||
const subType = readUint16BE(bytes, 52);
|
||||
const version = readUint16BE(bytes, 54);
|
||||
const type = readUint16BE(bytes, 82);
|
||||
const subType = readUint16BE(bytes, 84);
|
||||
const version = readUint16BE(bytes, 86);
|
||||
const bodyBytes = bytes.slice(BCH_FRAME_HEADER_SIZE);
|
||||
const body = parseBlockchainBody(type, subType, version, bodyBytes);
|
||||
return {
|
||||
frameCode,
|
||||
prevHashHex: bytesToHex(bytes.slice(2, 34)),
|
||||
back32HashHex: bytesToHex(bytes.slice(34, 66)),
|
||||
blockSize,
|
||||
blockNumber: readInt32BE(bytes, 38),
|
||||
timestampSec: readInt64BE(bytes, 42),
|
||||
blockNumber: readInt32BE(bytes, 70),
|
||||
timestampSec: readInt64BE(bytes, 74),
|
||||
type,
|
||||
subType,
|
||||
version,
|
||||
@@ -2501,7 +2505,7 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
let offset = 0;
|
||||
while (offset < data.length) {
|
||||
if (data.length - offset < BCH_FRAME_HEADER_SIZE) throw new Error(`Frame обрывается на смещении ${offset}`);
|
||||
const blockSize = readInt32BE(data, offset + 34);
|
||||
const blockSize = readInt32BE(data, offset + 66);
|
||||
if (blockSize < BCH_FRAME_HEADER_SIZE || offset + blockSize > data.length) throw new Error(`Некорректный blockSize ${blockSize} на смещении ${offset}`);
|
||||
blocks.push(await parseBlockchainBlock(data.slice(offset, offset + blockSize)));
|
||||
offset += blockSize;
|
||||
@@ -3345,7 +3349,7 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
const oldSetContentStatus = setContentStatus;
|
||||
setContentStatus = function(kind,text){ oldSetContentStatus(kind,text); const el=document.getElementById('v3-status'); if(el) el.textContent=text; v3Log(text); };
|
||||
function v3Theme(theme){ document.documentElement.dataset.theme=theme; localStorage.setItem('shine.viewer.theme',theme); const b=document.getElementById('v3-theme'); if(b)b.textContent=theme==='dark'?'☀':'☾'; }
|
||||
function v3RenderBlocks(){ const host=document.getElementById('v3-block-view'); if(!host)return; host.innerHTML=''; const wrap=document.createElement('div'); wrap.className='v3-blocks'; const blocks=(currentBlockchainView?.rawBlocks||V3.blocks||[]).slice().sort((a,b)=>b.blockNumber-a.blockNumber); blocks.forEach(b=>{ const d=document.createElement('details'); d.className='v3-block'; const sm=document.createElement('summary'); sm.textContent=`#${b.blockNumber} · type ${b.type}/${b.subType} · ${formatTimestamp(Number(b.timestampSec)*1000)}`; const pre=document.createElement('pre'); pre.textContent=JSON.stringify({blockNumber:b.blockNumber,type:b.type,subType:b.subType,version:b.version,hash:b.hashHex,prevHash:b.prevHashHex,arweaveId:b.arweaveId,body:b.body},(k,v)=>typeof v==='bigint'?String(v):v,2); d.append(sm,pre); wrap.appendChild(d); }); if(!blocks.length)wrap.textContent='Блоки ещё не загружены.'; host.appendChild(wrap); }
|
||||
function v3RenderBlocks(){ const host=document.getElementById('v3-block-view'); if(!host)return; host.innerHTML=''; const wrap=document.createElement('div'); wrap.className='v3-blocks'; const blocks=(currentBlockchainView?.rawBlocks||V3.blocks||[]).slice().sort((a,b)=>b.blockNumber-a.blockNumber); blocks.forEach(b=>{ const d=document.createElement('details'); d.className='v3-block'; const sm=document.createElement('summary'); sm.textContent=`#${b.blockNumber} · type ${b.type}/${b.subType} · ${formatTimestamp(Number(b.timestampSec)*1000)}`; const pre=document.createElement('pre'); pre.textContent=JSON.stringify({blockNumber:b.blockNumber,type:b.type,subType:b.subType,version:b.version,hash:b.hashHex,prevHash:b.prevHashHex,back32Hash:b.back32HashHex,arweaveId:b.arweaveId,body:b.body},(k,v)=>typeof v==='bigint'?String(v):v,2); d.append(sm,pre); wrap.appendChild(d); }); if(!blocks.length)wrap.textContent='Блоки ещё не загружены.'; host.appendChild(wrap); }
|
||||
function v3SetView(mode){ const bv=document.getElementById('v3-block-view'), cb=document.getElementById('content-browser'); document.getElementById('v3-channel-tab').classList.toggle('is-active',mode==='channel'); document.getElementById('v3-blocks-tab').classList.toggle('is-active',mode==='blocks'); if(bv)bv.hidden=mode!=='blocks'; if(cb)cb.hidden=mode==='blocks'; if(mode==='blocks')v3RenderBlocks(); }
|
||||
async function v3ClearCache(){ try{ const keys=Object.keys(localStorage).filter(k=>k.startsWith('shine.viewer.data.')); keys.forEach(k=>localStorage.removeItem(k)); if('caches' in window){ for(const k of await caches.keys()) if(k.startsWith('shine-viewer-')) await caches.delete(k); } v3Log('Кэш данных очищен'); }catch(e){v3Log('Ошибка очистки кэша: '+e.message);} }
|
||||
function v3CacheKey(key,channel){return 'shine.viewer.author-chain.'+String(key);}
|
||||
@@ -3372,7 +3376,7 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
function v3Verification(blocks){
|
||||
blocks=(blocks||[]).slice().sort((a,b)=>a.blockNumber-b.blockNumber);
|
||||
const byNum=new Map(blocks.map(b=>[Number(b.blockNumber),b]));
|
||||
const result={total:blocks.length,frameHash:{ok:blocks.length,bad:0,na:0},global:{ok:0,bad:0,na:0},channel:{ok:0,bad:0,na:0},owner:{ok:0,bad:0,na:0},signature:{ok:0,bad:0,na:blocks.length},issues:[]};
|
||||
const result={total:blocks.length,frameHash:{ok:blocks.length,bad:0,na:0},global:{ok:0,bad:0,na:0},back32:{ok:0,bad:0,na:0},channel:{ok:0,bad:0,na:0},owner:{ok:0,bad:0,na:0},signature:{ok:0,bad:0,na:blocks.length},issues:[]};
|
||||
for(const b of blocks){
|
||||
// hashHex is SHA-256(Frame) calculated locally by parseBlockchainBlock.
|
||||
if(!b.hashHex){result.frameHash.ok--;result.frameHash.na++;}
|
||||
@@ -3384,6 +3388,16 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
else if(String(prev.hashHex).toLowerCase()===String(b.prevHashHex).toLowerCase()) result.global.ok++;
|
||||
else{result.global.bad++;result.issues.push({kind:'global',state:'bad',block:b.blockNumber,text:`prevHash не совпадает с SHA-256 блока #${prev.blockNumber}`});}
|
||||
}
|
||||
const back32=String(b.back32HashHex||'');
|
||||
if(Number(b.blockNumber)<32){
|
||||
if(v3ZeroHash(back32)) result.back32.ok++;
|
||||
else{result.back32.bad++;result.issues.push({kind:'back32',state:'bad',block:b.blockNumber,text:'Для блока <32 back32Hash должен быть нулевым'});}
|
||||
} else {
|
||||
const target=byNum.get(Number(b.blockNumber)-32);
|
||||
if(!target){result.back32.na++;result.issues.push({kind:'back32',state:'na',block:b.blockNumber,text:`Нет блока #${Number(b.blockNumber)-32} для проверки back32Hash`});}
|
||||
else if(String(target.hashHex).toLowerCase()===back32.toLowerCase()) result.back32.ok++;
|
||||
else{result.back32.bad++;result.issues.push({kind:'back32',state:'bad',block:b.blockNumber,text:`back32Hash не совпадает с SHA-256 блока #${Number(b.blockNumber)-32}`});}
|
||||
}
|
||||
const body=b.body||{};
|
||||
if(body.kind==='text_line' || body.kind==='create_channel'){
|
||||
const pn=Number(body.prevLineNumber||0), ph=String(body.prevLineHashHex||'');
|
||||
@@ -3402,8 +3416,8 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
function v3UpdateVerification(){
|
||||
const r=v3Verification(currentBlockchainView?.rawBlocks||V3.blocks||[]);
|
||||
V3.verification=r;
|
||||
const bad=r.global.bad+r.channel.bad+r.frameHash.bad+r.owner.bad+r.signature.bad;
|
||||
const checked=r.global.ok+r.channel.ok;
|
||||
const bad=r.global.bad+r.back32.bad+r.channel.bad+r.frameHash.bad+r.owner.bad+r.signature.bad;
|
||||
const checked=r.global.ok+r.back32.ok+r.channel.ok;
|
||||
const el=document.getElementById('v3-status');
|
||||
if(el && r.total) el.textContent=`${bad?'⚠':'✓'} Хэши ${checked} · global ${v3MetricText(r.global)} · канал ${v3MetricText(r.channel)} · owner ${v3MetricText(r.owner)}`;
|
||||
return r;
|
||||
@@ -3416,6 +3430,7 @@ var solanaWeb3=function(exports){"use strict";function getDefaultExportFromCjs(x
|
||||
document.getElementById('v3-verify-summary').innerHTML=
|
||||
v3VerifyCard('SHA-256 Frame',r.frameHash,'вычислен локально')+
|
||||
v3VerifyCard('Общая цепочка',r.global,'prevHash')+
|
||||
v3VerifyCard('Резерв N−32',r.back32,'back32Hash')+
|
||||
v3VerifyCard('Цепочки каналов',r.channel,'prevLineHash')+
|
||||
v3VerifyCard('Arweave owner',r.owner,'совпадение выборки owner');
|
||||
const sig=document.getElementById('v3-signature-note');
|
||||
|
||||
Reference in New Issue
Block a user