Bounded test succeeded; native RandomX miner accepted one block
This commit is contained in:
@@ -5,6 +5,7 @@ import { assertCustodyDbActionAllowedOnNetwork, assertMainnetSchemaMigrationAckn
|
||||
assertPilotSchemaMigrationAcknowledged, assertPilotCustodyIdentityAcknowledged,
|
||||
assertPilotReservationGrantAcknowledged, assertPilotAddressGrantAcknowledged,
|
||||
assertPilotObserverGrantAcknowledged,
|
||||
assertPilotDepositReviewAcknowledged,
|
||||
parseCustodyDbArguments } from '../server/market/custody-db-args.ts';
|
||||
|
||||
test('custody database CLI parses two-argument deposit operations without shifting arguments', () => {
|
||||
@@ -23,6 +24,14 @@ test('custody database CLI parses two-argument deposit operations without shifti
|
||||
assert.deepEqual(parseCustodyDbArguments(['grant-monero-withdrawal-runtime', 'monero_withdrawal']), {
|
||||
action: 'grant-monero-withdrawal-runtime', argument: 'monero_withdrawal', extraArgument: undefined,
|
||||
});
|
||||
assert.deepEqual(parseCustodyDbArguments(['grant-pilot-monero-review-runtime', 'pilot_deposit_review']), {
|
||||
action: 'grant-pilot-monero-review-runtime', argument: 'pilot_deposit_review', extraArgument: undefined,
|
||||
});
|
||||
assert.deepEqual(parseCustodyDbArguments(['pilot-deposit-prepare-review', 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
|
||||
`${'b'.repeat(64)}:${'c'.repeat(64)}`]), {
|
||||
action: 'pilot-deposit-prepare-review', argument: 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa',
|
||||
extraArgument: `${'b'.repeat(64)}:${'c'.repeat(64)}`,
|
||||
});
|
||||
assert.deepEqual(parseCustodyDbArguments(['initialize-pilot-custody-identity', 'AAAAAAAA-AAAA-4AAA-8AAA-AAAAAAAAAAAA']), {
|
||||
action: 'initialize-pilot-custody-identity', argument: 'AAAAAAAA-AAAA-4AAA-8AAA-AAAAAAAAAAAA', extraArgument: undefined,
|
||||
});
|
||||
@@ -60,12 +69,14 @@ test('mainnet reviewed deposit operations require exact credit-only acknowledgem
|
||||
assert.doesNotThrow(() => assertMainnetCustodyOperationAcknowledged('grant-monero-withdrawal-runtime', undefined));
|
||||
});
|
||||
|
||||
test('pilot custody CLI permits only additive schema migration and identity-only initialization', () => {
|
||||
test('pilot custody CLI permits only pilot-scoped schema, identity, role, and review-preparation actions', () => {
|
||||
assert.doesNotThrow(() => assertPilotCustodyActionAllowed('migrate-pilot-schema', true));
|
||||
assert.doesNotThrow(() => assertPilotCustodyActionAllowed('initialize-pilot-custody-identity', true));
|
||||
assert.doesNotThrow(() => assertPilotCustodyActionAllowed('grant-pilot-deposit-reservation-runtime', true));
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('grant-monero-observer-runtime', true), /only pilot schema migration/);
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('deposit-stage-credit', true), /only pilot schema migration/);
|
||||
assert.doesNotThrow(() => assertPilotCustodyActionAllowed('grant-pilot-monero-review-runtime', true));
|
||||
assert.doesNotThrow(() => assertPilotCustodyActionAllowed('pilot-deposit-prepare-review', true));
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('grant-monero-observer-runtime', true), /pilot-specific schema/);
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('deposit-stage-credit', true), /pilot-specific schema/);
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('initialize-pilot-custody-identity', false), /requires the pilot profile/);
|
||||
assert.throws(() => assertPilotSchemaMigrationAcknowledged('migrate-pilot-schema', undefined), /acknowledgement/);
|
||||
assert.throws(() => assertPilotSchemaMigrationAcknowledged('migrate-pilot-schema', 'yes'), /acknowledgement/);
|
||||
@@ -84,6 +95,13 @@ test('pilot custody CLI permits only additive schema migration and identity-only
|
||||
assert.throws(() => assertPilotObserverGrantAcknowledged('grant-pilot-monero-observer-runtime', undefined), /no-credit acknowledgement/);
|
||||
assert.throws(() => assertPilotObserverGrantAcknowledged('grant-pilot-monero-observer-runtime', 'reviewed-credit-only'), /no-credit acknowledgement/);
|
||||
assert.doesNotThrow(() => assertPilotObserverGrantAcknowledged('grant-pilot-monero-observer-runtime', 'pilot-observation-only-no-credit'));
|
||||
for (const action of ['grant-pilot-monero-review-runtime', 'pilot-deposit-prepare-review'] as const) {
|
||||
assert.throws(() => assertPilotDepositReviewAcknowledged(action, undefined), /acknowledgement/);
|
||||
assert.throws(() => assertPilotDepositReviewAcknowledged(action, 'yes'), /acknowledgement/);
|
||||
}
|
||||
assert.doesNotThrow(() => assertPilotDepositReviewAcknowledged('grant-pilot-monero-review-runtime', 'read-only-pilot-review-role-only'));
|
||||
assert.doesNotThrow(() => assertPilotDepositReviewAcknowledged('pilot-deposit-prepare-review', 'pilot-deposit-review-preparation-only'));
|
||||
assert.throws(() => assertPilotCustodyActionAllowed('pilot-deposit-prepare-review', false), /requires the pilot profile/);
|
||||
});
|
||||
|
||||
test('custody database CLI rejects unknown, missing, empty, and excess arguments', () => {
|
||||
|
||||
@@ -3,6 +3,7 @@ import assert from 'node:assert/strict';
|
||||
import { mkdtemp, writeFile, chmod, rm } from 'node:fs/promises';
|
||||
import { join } from 'node:path';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { execFileSync } from 'node:child_process';
|
||||
import { postgresConfig } from '../server/market/postgres-config.ts';
|
||||
|
||||
test('PostgreSQL verified TLS remains the default and cannot be downgraded through URL options', async t => {
|
||||
@@ -27,6 +28,25 @@ test('PostgreSQL verified TLS remains the default and cannot be downgraded throu
|
||||
await assert.rejects(postgresConfig(env), /configuration/);
|
||||
});
|
||||
|
||||
test('PostgreSQL public CA is validated separately from owner-only credential URL files', async t => {
|
||||
if (process.platform === 'win32') return;
|
||||
const dir = await mkdtemp(join(tmpdir(), 'wikideck-ca-'));
|
||||
t.after(() => rm(dir, { recursive: true, force: true }));
|
||||
const urlFile = join(dir, 'connection'), caFile = join(dir, 'ca.crt'), keyFile = join(dir, 'ca.key');
|
||||
await writeFile(urlFile, 'postgresql://fixture:fixture-only@database/custody', { mode: 0o600 });
|
||||
execFileSync('openssl', ['req', '-x509', '-newkey', 'rsa:2048', '-sha256', '-nodes', '-days', '2',
|
||||
'-subj', '/CN=fixture CA', '-keyout', keyFile, '-out', caFile], { stdio: 'ignore' });
|
||||
await chmod(urlFile, 0o600); await chmod(caFile, 0o644); await chmod(keyFile, 0o600);
|
||||
const config = await postgresConfig({ WIKIDECK_CUSTODY_PG_URL_FILE: urlFile, WIKIDECK_CUSTODY_PG_CA_FILE: caFile });
|
||||
assert.equal((config.ssl as { rejectUnauthorized: boolean }).rejectUnauthorized, true);
|
||||
assert.ok((config.ssl as { ca: string }).ca.includes('BEGIN CERTIFICATE'));
|
||||
await chmod(urlFile, 0o644);
|
||||
await assert.rejects(postgresConfig({ WIKIDECK_CUSTODY_PG_URL_FILE: urlFile, WIKIDECK_CUSTODY_PG_CA_FILE: caFile }), /configuration/);
|
||||
await chmod(urlFile, 0o600);
|
||||
await writeFile(caFile, 'not a certificate', { mode: 0o644 }); await chmod(caFile, 0o644);
|
||||
await assert.rejects(postgresConfig({ WIKIDECK_CUSTODY_PG_URL_FILE: urlFile, WIKIDECK_CUSTODY_PG_CA_FILE: caFile }), /configuration/);
|
||||
});
|
||||
|
||||
test('infrastructure-managed transport requires exact opt-in and rejects mixed TLS/test configuration', async t => {
|
||||
const dir = await mkdtemp(join(tmpdir(), 'wikideck-infrastructure-'));
|
||||
t.after(() => rm(dir, { recursive: true, force: true }));
|
||||
|
||||
@@ -17,6 +17,7 @@ import { CustodyMarket } from '../../server/market/custody.ts';
|
||||
import { migrateCustody, grantCustodyRuntime, grantMoneroObserverRuntime, CUSTODY_SCHEMA_V1, CUSTODY_SCHEMA_V1_DIGEST,
|
||||
grantMoneroDepositCreditRuntime, grantMoneroDepositAllocatorRuntime, grantMoneroWithdrawalRuntime,
|
||||
grantPilotDepositReservationRuntime, grantPilotDepositAddressRuntime, grantPilotMoneroObserverRuntime,
|
||||
grantPilotMoneroDepositReviewRuntime,
|
||||
CUSTODY_MIGRATION_V2,
|
||||
CUSTODY_SCHEMA_V2_DIGEST } from '../../server/market/postgres-schema.ts';
|
||||
import { parseMainnetCustodianId } from '../../server/market/mainnet-custody-identity.ts';
|
||||
@@ -670,6 +671,113 @@ test('pilot observations classify reserved-wallet outputs, persist replay/reorg
|
||||
}
|
||||
});
|
||||
|
||||
test('pilot review preparation is read-only, identity-bound, and fails closed on ineligible evidence', async t => {
|
||||
const admin = new Pool(config), database = `pilot_review_${randomUUID().replaceAll('-', '')}`;
|
||||
const role = `pilot_review_${randomUUID().replaceAll('-', '')}`;
|
||||
await admin.query(`CREATE DATABASE "${database}"`);
|
||||
const owner = new Pool({ ...config, database }), run = promisify(execFile);
|
||||
const custodianId = randomUUID(), generation = randomUUID(), fingerprint = 'c'.repeat(64), now = Date.now();
|
||||
const firstAddress = await syntheticSubaddress(31), secondAddress = await syntheticSubaddress(32);
|
||||
const suspenseAddress = await syntheticSubaddress(33);
|
||||
const code = `import { Pool } from 'pg';
|
||||
import { randomUUID } from 'node:crypto';
|
||||
import { CHAIN_ID } from './server/testnet/consensus.ts';
|
||||
import { initializePilotCustodyIdentity } from './server/market/pilot-custody-identity.ts';
|
||||
import { reservePilotMoneroDepositIndex } from './server/market/pilot-monero-deposit-allocation.ts';
|
||||
import { persistPilotMoneroObservationScan } from './server/market/pilot-monero-observation-store.ts';
|
||||
import { preparePilotMoneroDepositReview } from './server/market/pilot-monero-deposit-review.ts';
|
||||
const config={host:'127.0.0.1',database:process.env.DB,user:'postgres',ssl:false,max:4};
|
||||
const owner=new Pool(config), review=new Pool({...config,user:process.env.REVIEW_ROLE});
|
||||
const now=Number(process.env.NOW), generation=process.env.GENERATION, fingerprint=process.env.FINGERPRINT;
|
||||
const policy={minimumConfirmations:10,maximumObservationAgeMs:30000};
|
||||
const failed=async (generationId,observationId,at=now+300,selectedPolicy=policy)=>{
|
||||
try { await preparePilotMoneroDepositReview(review,{walletGenerationId:generationId,observationId},selectedPolicy,at); return false; }
|
||||
catch { return true; }
|
||||
};
|
||||
try {
|
||||
const identity=await initializePilotCustodyIdentity(owner,process.env.CUSTODIAN,now-100);
|
||||
const reserve=async (beneficiary,requestDigest)=>{
|
||||
const intent={requestId:randomUUID(),custodianId:identity.custodianId,marketNetwork:identity.marketNetwork,
|
||||
marketChainId:CHAIN_ID,moneroNetwork:'mainnet',beneficiary,walletGenerationId:generation,walletFingerprint:fingerprint,
|
||||
accountIndex:0,requestDigest};
|
||||
return (await reservePilotMoneroDepositIndex(owner,identity,intent,now-50)).reservation;
|
||||
};
|
||||
const first=await reserve('a'.repeat(64),'b'.repeat(64));
|
||||
const second=await reserve('c'.repeat(64),'d'.repeat(64));
|
||||
for (const [reservation,address] of [[first,process.env.FIRST_ADDRESS],[second,process.env.SECOND_ADDRESS]]) {
|
||||
await owner.query("UPDATE wk_custody.pilot_monero_deposit_reservations SET status='creating',create_started_at=$2 WHERE allocation_id=$1",
|
||||
[reservation.allocationId,now-40]);
|
||||
await owner.query("UPDATE wk_custody.pilot_monero_deposit_reservations SET status='registered',monero_address=$2,registered_at=$3 WHERE allocation_id=$1",
|
||||
[reservation.allocationId,address,now-30]);
|
||||
}
|
||||
const assigned={observationId:'e'.repeat(64)+':'+'f'.repeat(64),transactionId:'e'.repeat(64),address:process.env.FIRST_ADDRESS,
|
||||
amountAtomicXmr:'9007199254740993',height:100,confirmations:11,timestamp:Math.floor(now/1000)-100,
|
||||
unlockTime:'0',accountIndex:0,addressIndex:0,outputPublicKey:'f'.repeat(64),globalOutputIndex:50,
|
||||
locked:false,doubleSpendSeen:false};
|
||||
const futureUnlock={...assigned,observationId:'1'.repeat(64)+':'+'2'.repeat(64),transactionId:'1'.repeat(64),
|
||||
address:process.env.SECOND_ADDRESS,height:101,confirmations:10,unlockTime:String(Math.floor((now+60000)/1000)),
|
||||
addressIndex:1,outputPublicKey:'2'.repeat(64),globalOutputIndex:51};
|
||||
const suspense={...assigned,observationId:'3'.repeat(64)+':'+'4'.repeat(64),transactionId:'3'.repeat(64),
|
||||
address:process.env.SUSPENSE_ADDRESS,amountAtomicXmr:'7',height:102,confirmations:9,unlockTime:'0',addressIndex:2,
|
||||
outputPublicKey:'4'.repeat(64),globalOutputIndex:52};
|
||||
const persist=(scanId,expectedScanHeight,fromHeight,throughHeight,walletHeight,incoming,scannedAt)=>persistPilotMoneroObservationScan(owner,
|
||||
{scanId,walletGenerationId:generation,walletFingerprint:fingerprint,expectedScanHeight,scannedAt,
|
||||
page:{network:'mainnet',walletHeight,fromHeight,throughHeight,primaryAddress:process.env.PRIMARY_ADDRESS,incoming}});
|
||||
await persist(randomUUID(),0,0,110,110,[assigned,futureUnlock,suspense],now+100);
|
||||
const subject=await preparePilotMoneroDepositReview(review,{walletGenerationId:generation,observationId:assigned.observationId},policy,now+300);
|
||||
const stricterFloorRejected=await failed(generation,assigned.observationId,now+300,{...policy,minimumConfirmations:12});
|
||||
const futureUnlockRejected=await failed(generation,futureUnlock.observationId);
|
||||
const unallocatedRejected=await failed(generation,suspense.observationId);
|
||||
const staleRejected=await failed(generation,assigned.observationId,now+40000);
|
||||
const before=await owner.query('SELECT (SELECT count(*)::int FROM wk_custody.journals) AS journals, '+
|
||||
'(SELECT count(*)::int FROM wk_custody.entries) AS entries, '+
|
||||
'(SELECT count(*)::int FROM wk_custody.accounts) AS accounts, '+
|
||||
'(SELECT count(*)::int FROM wk_custody.monero_deposit_credit_events) AS credits');
|
||||
const changed={...assigned,amountAtomicXmr:'9007199254740994',confirmations:21};
|
||||
await persist(randomUUID(),110,100,120,120,[changed,{...futureUnlock,confirmations:20}],now+200);
|
||||
const changedHistoryRejected=await failed(generation,assigned.observationId,now+300);
|
||||
let updateDenied=false, financialReadDenied=false;
|
||||
try { await review.query("UPDATE wk_custody.pilot_monero_observations SET locked=true"); } catch { updateDenied=true; }
|
||||
try { await review.query('SELECT * FROM wk_custody.journals'); } catch { financialReadDenied=true; }
|
||||
console.log(JSON.stringify({subject,stricterFloorRejected,futureUnlockRejected,unallocatedRejected,staleRejected,
|
||||
changedHistoryRejected,before:before.rows[0],updateDenied,financialReadDenied}));
|
||||
} finally { await review.end(); await owner.end(); }`;
|
||||
try {
|
||||
await migrateCustody(owner);
|
||||
await admin.query(`CREATE ROLE "${role}" LOGIN`);
|
||||
await grantPilotMoneroDepositReviewRuntime(owner, role);
|
||||
const privileges = await owner.query(`SELECT
|
||||
has_table_privilege($1,'wk_custody.pilot_monero_observations','SELECT') AS read_observations,
|
||||
has_table_privilege($1,'wk_custody.pilot_monero_observations','UPDATE') AS write_observations,
|
||||
has_table_privilege($1,'wk_custody.pilot_monero_observation_events','INSERT') AS append_events,
|
||||
has_table_privilege($1,'wk_custody.accounts','SELECT') AS read_accounts,
|
||||
has_table_privilege($1,'wk_custody.journals','SELECT') AS read_journals`, [role]);
|
||||
assert.deepEqual(Object.values(privileges.rows[0]), [true, false, false, false, false]);
|
||||
const result = JSON.parse((await run(process.execPath, ['--experimental-strip-types', '--input-type=module', '-e', code], {
|
||||
env: { ...process.env, WIKIDECK_NETWORK: 'pilot', WIKIDECK_PILOT_MODE: 'private-mock-only', DB: database,
|
||||
REVIEW_ROLE: role, CUSTODIAN: custodianId, GENERATION: generation, FINGERPRINT: fingerprint, NOW: String(now),
|
||||
FIRST_ADDRESS: firstAddress, SECOND_ADDRESS: secondAddress, SUSPENSE_ADDRESS: suspenseAddress,
|
||||
PRIMARY_ADDRESS: ADDITIONAL_MARKET_FEE.address },
|
||||
})).stdout.trim());
|
||||
assert.equal(result.subject.policyVersion, 'pilot-monero-deposit-review-v1');
|
||||
assert.equal(result.subject.preparationOnly, true); assert.equal(result.subject.crediting, 'disabled');
|
||||
assert.equal(result.subject.marketNetwork, 'wikideck-randomx-pilot-1'); assert.equal(result.subject.moneroNetwork, 'mainnet');
|
||||
assert.equal(result.subject.amountAtomicXmr, '9007199254740993');
|
||||
assert.equal(result.subject.confirmations, 11); assert.equal(result.subject.minimumConfirmations, 10);
|
||||
assert.equal(result.subject.eventHistoryCount, 1); assert.match(result.subject.subjectDigest, /^[a-f0-9]{64}$/);
|
||||
assert.equal(result.stricterFloorRejected, true); assert.equal(result.futureUnlockRejected, true);
|
||||
assert.equal(result.unallocatedRejected, true); assert.equal(result.staleRejected, true);
|
||||
assert.equal(result.changedHistoryRejected, true); assert.equal(result.updateDenied, true);
|
||||
assert.equal(result.financialReadDenied, true);
|
||||
assert.deepEqual(result.before, { journals: 0, entries: 0, accounts: 0, credits: 0 });
|
||||
} finally {
|
||||
await owner.end();
|
||||
await admin.query(`DROP DATABASE IF EXISTS "${database}" WITH (FORCE)`);
|
||||
await admin.query(`DROP ROLE IF EXISTS "${role}"`);
|
||||
await admin.end();
|
||||
}
|
||||
});
|
||||
|
||||
test('mainnet custody identity bootstrap is one-time, chain-bound, and does not open withdrawals', async t => {
|
||||
assert.equal(parseMainnetCustodianId('AAAAAAAA-AAAA-4AAA-8AAA-AAAAAAAAAAAA'), 'aaaaaaaa-aaaa-4aaa-8aaa-aaaaaaaaaaaa');
|
||||
assert.throws(() => parseMainnetCustodianId('not-a-uuid'), /Invalid mainnet custodian UUID/);
|
||||
|
||||
Reference in New Issue
Block a user