First deposit integration slice
This commit is contained in:
@@ -206,7 +206,7 @@ test('custody schema v1 upgrades additively through v3 without dropping existing
|
||||
try {
|
||||
await migrateCustody(admin); await migrateCustody(admin);
|
||||
const versions = await admin.query('SELECT version FROM wk_custody.schema_versions ORDER BY version');
|
||||
assert.deepEqual(versions.rows.map(row => Number(row.version)), [1, 2, 3]);
|
||||
assert.deepEqual(versions.rows.map(row => Number(row.version)), [1, 2, 3, 4]);
|
||||
assert.equal((await admin.query("SELECT value FROM wk_custody.custody_meta WHERE key='v1-preserved-marker'")).rows[0].value,
|
||||
'existing-test-data');
|
||||
for (const table of ['monero_observer_state', 'monero_transfer_observations', 'monero_observation_events', 'monero_observation_scans']) {
|
||||
@@ -229,7 +229,7 @@ test('custody schema v2 upgrades explicitly to v3 address-allocation registry',
|
||||
await client.query('COMMIT');
|
||||
await migrateCustody(admin); await migrateCustody(admin);
|
||||
const versions = await admin.query('SELECT version FROM wk_custody.schema_versions ORDER BY version');
|
||||
assert.deepEqual(versions.rows.map(row => Number(row.version)), [1, 2, 3]);
|
||||
assert.deepEqual(versions.rows.map(row => Number(row.version)), [1, 2, 3, 4]);
|
||||
assert.equal((await admin.query("SELECT value FROM wk_custody.custody_meta WHERE key='v2-marker'")).rows[0].value, 'preserve');
|
||||
} catch (error) { await client.query('ROLLBACK').catch(() => {}); throw error; }
|
||||
finally { client.release(); await admin.end(); }
|
||||
@@ -334,11 +334,11 @@ test('Monero scan persistence is idempotent, reorg-visible and never posts custo
|
||||
await assert.rejects(grantMoneroObserverRuntime(f.admin, 'custody_runtime'), /separate role/);
|
||||
const runtime = new Pool({ ...f.runtime, user: 'monero_observer' });
|
||||
const custodyRuntime = new Pool(f.runtime), wallet = 'd'.repeat(64), scan1 = randomUUID();
|
||||
const txid = 'e'.repeat(64), observationId = `${txid}:0:4`;
|
||||
const txid = 'e'.repeat(64), outputPublicKey = 'f'.repeat(64), observationId = `${txid}:${outputPublicKey}`;
|
||||
const observation = { observationId, transactionId: txid, amountAtomicXmr: '9007199254740993', height: 95,
|
||||
address: ADDITIONAL_MARKET_FEE.address,
|
||||
confirmations: 6, timestamp: 1_800_000_000, unlockTime: '0', accountIndex: 0, addressIndex: 4,
|
||||
locked: false, doubleSpendSeen: false };
|
||||
outputPublicKey, globalOutputIndex: 123, locked: false, doubleSpendSeen: false };
|
||||
const page = { network: 'mainnet' as const, walletHeight: 100, fromHeight: 0, throughHeight: 100,
|
||||
primaryAddress: ADDITIONAL_MARKET_FEE.address, incoming: [observation] };
|
||||
try {
|
||||
@@ -369,12 +369,29 @@ test('Monero scan persistence is idempotent, reorg-visible and never posts custo
|
||||
incoming: [{ ...observation, confirmations: 26 }] } });
|
||||
assert.equal(reappeared.reappeared, 1);
|
||||
|
||||
const observed = await runtime.query(`SELECT amount_atomic_xmr::text AS amount,monero_address,currently_present FROM wk_custody.monero_transfer_observations
|
||||
const observed = await runtime.query(`SELECT amount_atomic_xmr::text AS amount,monero_address,output_public_key,global_output_index,currently_present FROM wk_custody.monero_transfer_observations
|
||||
WHERE wallet_fingerprint=$1 AND observation_id=$2`, [wallet, observationId]);
|
||||
assert.equal(observed.rows[0].amount, '9007199254740993'); assert.equal(observed.rows[0].currently_present, true);
|
||||
assert.equal(observed.rows[0].monero_address, ADDITIONAL_MARKET_FEE.address);
|
||||
assert.equal(observed.rows[0].output_public_key, outputPublicKey); assert.equal(Number(observed.rows[0].global_output_index), 123);
|
||||
|
||||
const reorgMovedOutput = await persistMoneroObservationScan(runtime, { scanId: randomUUID(), walletFingerprint: wallet,
|
||||
expectedScanHeight: 120, scannedAt: 1_800_000_325,
|
||||
page: { ...page, fromHeight: 90, walletHeight: 121, throughHeight: 121,
|
||||
incoming: [{ ...observation, height: 96, confirmations: 26 }] } });
|
||||
assert.equal(reorgMovedOutput.changed, 1, 'same output re-included at a different height must be visible as changed evidence');
|
||||
const updated = await runtime.query(`SELECT block_height,output_public_key FROM wk_custody.monero_transfer_observations
|
||||
WHERE wallet_fingerprint=$1 AND observation_id=$2`, [wallet, observationId]);
|
||||
assert.equal(Number(updated.rows[0].block_height), 96);
|
||||
assert.equal(updated.rows[0].output_public_key, outputPublicKey, 'output identity survives a reorg/re-inclusion');
|
||||
|
||||
await assert.rejects(persistMoneroObservationScan(runtime, { scanId: randomUUID(), walletFingerprint: wallet,
|
||||
expectedScanHeight: 121, scannedAt: 1_800_000_350,
|
||||
page: { ...page, fromHeight: 90, walletHeight: 121, throughHeight: 121,
|
||||
incoming: [{ ...observation, transactionId: 'a'.repeat(64), observationId: `${'a'.repeat(64)}:${outputPublicKey}`, height: 96, confirmations: 26 }] } }),
|
||||
/output key|unique/i, 'one wallet output key cannot be assigned to two transaction identities');
|
||||
const eventTypes = await runtime.query('SELECT event_type FROM wk_custody.monero_observation_events ORDER BY sequence');
|
||||
assert.deepEqual(eventTypes.rows.map(row => row.event_type), ['seen', 'not-seen', 'reappeared']);
|
||||
assert.deepEqual(eventTypes.rows.map(row => row.event_type), ['seen', 'not-seen', 'reappeared', 'changed']);
|
||||
await assert.rejects(runtime.query('UPDATE wk_custody.monero_observation_events SET event_type=\'seen\''));
|
||||
await assert.rejects(runtime.query('DELETE FROM wk_custody.monero_observation_scans'));
|
||||
await assert.rejects(runtime.query('SELECT count(*) FROM wk_custody.journals'), /permission denied/);
|
||||
|
||||
Reference in New Issue
Block a user