diff --git a/CITATIONS-UNRESOLVED.md b/CITATIONS-UNRESOLVED.md index c935ddf..c0045fa 100644 --- a/CITATIONS-UNRESOLVED.md +++ b/CITATIONS-UNRESOLVED.md @@ -1,7 +1,7 @@ # Citations in this repository that you cannot open This file is generated by the publication stager of this repository (scripts/legaturi-declaratie.cjs in the Aere working -tree) and enforced by legaturi.cjs. It is the complete list, measured on 2026-10-19, of every path cited in this +tree) and enforced by legaturi.cjs. It is the complete list, measured on 2026-10-20, of every path cited in this repository that does not resolve to a published file. A citation is a promise that a claim is checkable. Where the target is not published, or names a file the reader creates diff --git a/README.md b/README.md index 7a002dc..bb1b5ca 100644 --- a/README.md +++ b/README.md @@ -64,4 +64,4 @@ interface, command line and data (`definePolicy`, `verifyLedger`, `approve`, ... ## Licence -MIT, see [LICENSE](LICENSE). Files: 975 (pq-gateway 9, pq-kms 10, pq-secrets 6, pq-pki 6, crypto-inventory 73, verify-layer 56, proof-kinds 3, control-plane 27, agents 44, identity 24, proof-of-ai 3, ai-trust 6, verifiable-data 7, market-settlement 9, payments 8, conformance 646, device-identity 11, exposure-report 18, readiness 4). +MIT, see [LICENSE](LICENSE). Files: 976 (pq-gateway 9, pq-kms 10, pq-secrets 6, pq-pki 6, crypto-inventory 73, verify-layer 56, proof-kinds 3, control-plane 27, agents 44, identity 24, proof-of-ai 3, ai-trust 6, verifiable-data 7, market-settlement 10, payments 8, conformance 646, device-identity 11, exposure-report 18, readiness 4). diff --git a/market-settlement/piata.mjs b/market-settlement/piata.mjs index 73ab71b..8381de7 100644 --- a/market-settlement/piata.mjs +++ b/market-settlement/piata.mjs @@ -71,7 +71,14 @@ export async function cronologie({ ethers, provider, market, artifact, jobId, fr const events = []; for (const l of brute) { if (!blocuri.has(l.blockHash)) blocuri.set(l.blockHash, await provider.getBlock(l.blockHash)); - if (!txs.has(l.transactionHash)) txs.set(l.transactionHash, await provider.getTransaction(l.transactionHash)); + // 2026-10-20: the transaction is read as the node serves it and only its sender is taken (in the checksummed form ethers gave): + // ethers' getTransaction decodes it, and it does not know the post-quantum type 0x50 (AIP-20, live on 28001), so a job event sent + // with a post-quantum transaction made the whole timeline throw + if (!txs.has(l.transactionHash)) { + const raw = await provider.send('eth_getTransactionByHash', [l.transactionHash]); + if (!raw || !raw.from) throw new Error('transaction ' + l.transactionHash + ' not found'); + txs.set(l.transactionHash, { from: ethers.getAddress(raw.from) }); + } const b = blocuri.get(l.blockHash), t = txs.get(l.transactionHash); const args = {}; l.fragment.inputs.forEach((inp, i) => { args[inp.name] = s(l.args[i]); }); events.push({ name: l.fragment.name, args, blockNumber: l.blockNumber, blockHash: l.blockHash, timestamp: b.timestamp, txHash: l.transactionHash, from: t.from, logIndex: l.index }); diff --git a/market-settlement/proba-cronologie-citire.mjs b/market-settlement/proba-cronologie-citire.mjs new file mode 100644 index 0000000..d7cf7ed --- /dev/null +++ b/market-settlement/proba-cronologie-citire.mjs @@ -0,0 +1,41 @@ +// proba-cronologie-citire.mjs (2026-10-20): piata.mjs ia acum expeditorul unui eveniment din tranzactia BRUTA (eth_getTransactionByHash, +// in forma cu majuscule de control), fiindca ethers nu decodeaza tipul post-cuantic 0x50 (AIP-20, viu pe 28001). Proba, NUMAI CITIRI: pentru +// fiecare eveniment din cea mai noua dovada dovezi/piata-28001-*.json (scrisa cu forma veche, getTransaction decodat de ethers), expeditorul +// citit acum brut e EXACT cel din dovada. Plus controlul ca forma bruta citeste si o tranzactie 0x50 reala de pe 28001, pe care ethers nu o +// decodeaza (o cauta in ultimele 400 de blocuri; daca nu gaseste, spune NEMASURAT pe acel rand, nu verde). +// (Cronologia intreaga nu se poate reciti: queryFilter de la blocul lucrarii pana la varf trece de limita de interval a RPC-ului testnetului.) +// Iesire: 0 egale, 1 diferite, 2 nu s-a putut masura. AERE_ETHERS_DIR= node proba-cronologie-citire.mjs +import fs from 'node:fs'; +import path from 'node:path'; +import { createRequire } from 'node:module'; +import { fileURLToPath } from 'node:url'; +const AICI = path.dirname(fileURLToPath(import.meta.url)); +// ethers ca la proba-piata-28001.mjs: AERE_ETHERS_DIR= (implicit contracts/ din arborele de dezvoltare) +const ETHERS_DIR = process.env.AERE_ETHERS_DIR || path.join(AICI, '..', '..', 'contracts'); +let ethers; try { ({ ethers } = createRequire(path.join(ETHERS_DIR, 'package.json'))('ethers')); } catch (e) { console.log('NEMASURAT: ethers nu se incarca din ' + ETHERS_DIR + ' (AERE_ETHERS_DIR)'); process.exit(2); } +const dov = fs.readdirSync(path.join(AICI, 'dovezi')).filter((f) => /^piata-28001-.*\.json$/.test(f)).sort().pop(); +if (!dov) { console.log('NEMASURAT: nicio dovada piata-28001-*.json'); process.exit(2); } +const D = JSON.parse(fs.readFileSync(path.join(AICI, 'dovezi', dov), 'utf8')); +const evs = []; const aduna = (o) => { if (!o || typeof o !== 'object') return; if (o.txHash && o.from && o.name) evs.push(o); for (const v of Object.values(o)) aduna(v); }; aduna(D); +if (!evs.length) { console.log('NEMASURAT: dovada ' + dov + ' nu are evenimente cu txHash si from'); process.exit(2); } +const provider = new ethers.JsonRpcProvider(process.env.AERE_RPC_28001 || 'https://testnet-rpc.aere.network', 28001, { staticNetwork: true }); +let rele = 0, vazute = new Map(); +for (const e of evs) { + if (vazute.has(e.txHash)) continue; + const raw = await provider.send('eth_getTransactionByHash', [e.txHash]); + if (!raw) { console.log('NEMASURAT: tranzactia ' + e.txHash + ' nu se mai gaseste'); process.exit(2); } + const nou = ethers.getAddress(raw.from); vazute.set(e.txHash, nou); + if (nou !== e.from) { rele++; console.log(' difera ' + e.txHash.slice(0, 14) + ': ' + nou + ' / ' + e.from); } +} +console.log(`dovada ${dov}: ${vazute.size} tranzactii distincte, ${evs.length} evenimente; expeditorul brut ${rele ? 'DIFERA la ' + rele : 'egal cu cel din dovada la toate'}`); +// controlul: o tranzactie 0x50 reala de pe 28001, ethers o refuza, forma bruta o citeste +const cap = await provider.getBlockNumber(); let t50 = null; +for (let bn = cap; bn > cap - 400 && !t50; bn--) { const b = await provider.send('eth_getBlockByNumber', ['0x' + bn.toString(16), true]); t50 = (b.transactions || []).find((t) => t.type === '0x50') || null; } +if (!t50) console.log('NEMASURAT (control): nicio tranzactie 0x50 in ultimele 400 de blocuri ale lui 28001'); +else { + let eth = 'citita'; try { await provider.getTransaction(t50.hash); } catch (x) { eth = 'refuzata (' + String(x.shortMessage || x.message).slice(0, 30) + ')'; } + const raw = await provider.send('eth_getTransactionByHash', [t50.hash]); + console.log('control 0x50 ' + t50.hash.slice(0, 14) + ': ethers ' + eth + '; forma bruta: expeditor ' + ethers.getAddress(raw.from)); +} +console.log(rele ? 'ROSU' : 'VERDE: expeditorii cititi brut sunt cei din dovada scrisa de forma veche'); +process.exitCode = rele ? 1 : 0;