30 lines
1.7 KiB
TypeScript
30 lines
1.7 KiB
TypeScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { merkleRoot, sha256, expectedKey, INITIAL_KEY, expectedTarget, MAX_TARGET, CHAIN_ID } from '../server/testnet/consensus.ts';
|
|
import { NETWORK, type TestnetBlock } from '../shared/testnet.ts';
|
|
|
|
test('Merkle commitments distinguish padded leaves, ordering, and node/leaf domains',()=>{
|
|
const a=sha256('a'),b=sha256('b'),c=sha256('c');
|
|
assert.notEqual(merkleRoot([a,b,c]),merkleRoot([a,b,c,c]));
|
|
assert.notEqual(merkleRoot([a,b]),merkleRoot([b,a]));
|
|
assert.notEqual(merkleRoot([a]),a);
|
|
assert.equal(merkleRoot([]),sha256(`${NETWORK}:empty`));
|
|
});
|
|
test('RandomX keys rotate only after the protocol delay using an ancestor, never a miner-selected seed',()=>{
|
|
const ancestors=Array.from({length:4160},(_,i)=>({hash:sha256(`block${i+1}`)} as TestnetBlock));
|
|
assert.equal(expectedKey(ancestors.slice(0,2047),2048),INITIAL_KEY);
|
|
assert.equal(expectedKey(ancestors.slice(0,2110),2111),INITIAL_KEY);
|
|
assert.equal(expectedKey(ancestors.slice(0,2111),2112),ancestors[2047].hash);
|
|
assert.equal(expectedKey(ancestors.slice(0,4158),4159),ancestors[2047].hash);
|
|
assert.equal(expectedKey(ancestors.slice(0,4159),4160),ancestors[4095].hash);
|
|
});
|
|
test('difficulty retargets deterministically at exact windows and is bounded',()=>{
|
|
assert.equal(expectedTarget([]),MAX_TARGET);
|
|
const blocks=Array.from({length:10},(_,i)=>({target:MAX_TARGET,createdAt:1000+i*30}as TestnetBlock));
|
|
assert.equal(expectedTarget(blocks.slice(0,9)),MAX_TARGET);
|
|
assert.equal(expectedTarget(blocks),MAX_TARGET);
|
|
const fast=blocks.map((b,i)=>({...b,createdAt:1000+i}));
|
|
assert.ok(BigInt(`0x${expectedTarget(fast)}`)<BigInt(`0x${MAX_TARGET}`));
|
|
assert.match(CHAIN_ID,/^[a-f0-9]{64}$/);
|
|
});
|