back32hash 5591: готово к тестам

Вроде как всё готово к тестам.
This commit is contained in:
AidarKC
2026-10-02 01:32:37 +03:00
parent e101e5c5f4
commit de8700f8e0
51 changed files with 337 additions and 18091 deletions
+17 -14
View File
@@ -2,6 +2,7 @@ import { createAns104DataItem, createAns104DataItemWithRawParts, parseAns104Data
import { base64ToBytes, bytesToBase64 } from './crypto-utils.js';
import { updateShineUserPdaOnSolana } from './shine-user-pda-service.js';
import { updateEncryptedUserSecrets } from './key-vault.js';
import { SHINE_APP_TAG_NAME, SHINE_APP_TAG_VALUE, SHINE_TYPE_TAG_NAME } from './protocol-tags.js';
const TE = new TextEncoder();
const ZERO_HASH = '0'.repeat(64);
@@ -33,23 +34,23 @@ function hexToBytes(hex) {
function bytesToHex(bytes) { return Array.from(bytes || [], (b)=>b.toString(16).padStart(2,'0')).join(''); }
function normalizeComment(value) { return String(value || '').trim().replace(/\r\n/g,'\n').replace(/\r/g,'\n'); }
function readFrameTimestampMs(frame) {
if (!(frame instanceof Uint8Array) || frame.length < 50) throw new Error('Некорректный SHiNE Frame');
const seconds = new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getBigInt64(42, false);
if (!(frame instanceof Uint8Array) || frame.length < 82) throw new Error('Некорректный SHiNE Frame');
const seconds = new DataView(frame.buffer, frame.byteOffset, frame.byteLength).getBigInt64(74, false);
return Number(seconds * 1000n);
}
function readFrameType(frame) {
if (!(frame instanceof Uint8Array) || frame.length < 56) throw new Error('Некорректный SHiNE Frame');
if (!(frame instanceof Uint8Array) || frame.length < 88) throw new Error('Некорректный SHiNE Frame');
const view=new DataView(frame.buffer,frame.byteOffset,frame.byteLength);
return { type:view.getUint16(50,false), subType:view.getUint16(52,false) };
return { type:view.getUint16(82,false), subType:view.getUint16(84,false) };
}
function readExplicitLinePrefix(frame) {
if (!(frame instanceof Uint8Array) || frame.length < 100) throw new Error('Некорректный line Frame');
if (!(frame instanceof Uint8Array) || frame.length < 132) throw new Error('Некорректный line Frame');
const view=new DataView(frame.buffer,frame.byteOffset,frame.byteLength);
return {
lineCode:view.getInt32(56,false),
prevLineNumber:view.getInt32(60,false),
prevLineHash:bytesToHex(frame.slice(64,96)),
lineSequence:view.getInt32(96,false),
lineCode:view.getInt32(88,false),
prevLineNumber:view.getInt32(92,false),
prevLineHash:bytesToHex(frame.slice(96,128)),
lineSequence:view.getInt32(128,false),
};
}
function makeForkBody({ lineCode=0, prevLineNumber, prevLineHash, lineSequence, oldBlockchainKeyB64, forkPointBlock, forkPointHash, forkPointTimestampMs, parentTipBlock, parentTipHash, parentTipTimestampMs, reasonCode, comment }) {
@@ -62,10 +63,10 @@ function makeForkBody({ lineCode=0, prevLineNumber, prevLineHash, lineSequence,
}
return concat(be32(lineCode),be32(prevLineNumber),hexToBytes(prevLineHash),be32(lineSequence),oldKey,be32(forkPointBlock),hexToBytes(forkPointHash),be64(forkPointTimestampMs),be32(parentTipBlock),hexToBytes(parentTipHash),be64(parentTipTimestampMs),be32(discarded),Uint8Array.of(Number(reasonCode)),be16(c.length),c);
}
function makeFrame({ prevHash, blockNumber, type, subType, version=1, body, timestampMs=Date.now() }) {
function makeFrame({ prevHash, back32Hash=ZERO_HASH, blockNumber, type, subType, version=1, body, timestampMs=Date.now() }) {
const bodyBytes=body || new Uint8Array(0);
const size=2+32+4+4+8+2+2+2+bodyBytes.length;
return concat(be16(1),hexToBytes(prevHash),be32(size),be32(blockNumber),be64(Math.floor(Number(timestampMs)/1000)),be16(type),be16(subType),be16(version),bodyBytes);
const size=2+32+32+4+4+8+2+2+2+bodyBytes.length;
return concat(be16(1),hexToBytes(prevHash),hexToBytes(back32Hash),be32(size),be32(blockNumber),be64(Math.floor(Number(timestampMs)/1000)),be16(type),be16(subType),be16(version),bodyBytes);
}
export const KEY_ROTATION_REASONS = Object.freeze([
@@ -153,8 +154,10 @@ export class KeyRotationClient {
comment:rotation.comment,
});
const techTimestampMs=Number(rotation.createdAtMs)||readFrameTimestampMs(tipParsed.data)+1000;
const techFrame=makeFrame({ prevHash:rotation.forkFromHash, blockNumber:cutoff+1, type:0, subType:TECH_FORK_SUBTYPE, version:1, body:forkBody, timestampMs:techTimestampMs });
const techRaw=await createAns104DataItem({ owner32, privateKey, data:techFrame, tags:[{name:'App',value:'test5590'},{name:'t',value:'tech'}] });
const techBlockNumber=cutoff+1;
const techBack32Hash=techBlockNumber<32 ? ZERO_HASH : String((await this.getBlock(source,techBlockNumber-32)).blockHash||'');
const techFrame=makeFrame({ prevHash:rotation.forkFromHash, back32Hash:techBack32Hash, blockNumber:techBlockNumber, type:0, subType:TECH_FORK_SUBTYPE, version:1, body:forkBody, timestampMs:techTimestampMs });
const techRaw=await createAns104DataItem({ owner32, privateKey, data:techFrame, tags:[{name:SHINE_APP_TAG_NAME,value:SHINE_APP_TAG_VALUE},{name:SHINE_TYPE_TAG_NAME,value:'tech'}] });
await this.addCandidate({ blockNumber:cutoff+1, prevBlockHash:rotation.forkFromHash, blockBytesB64:bytesToBase64(techRaw) });
onProgress({ phase:'copy', current:total, total });
}