Cold-restore rehearsal
This commit is contained in:
@@ -18,7 +18,7 @@ import { migrateCustody, grantCustodyRuntime } from '../../server/market/postgre
|
||||
import { importSqliteCustody } from '../../server/market/custody-import.ts';
|
||||
import { postgresConfig, custodyStorage } from '../../server/market/postgres-config.ts';
|
||||
import { openCustodyStorage } from '../../server/market/custody-storage.ts';
|
||||
import { createBackup } from '../../server/recovery.ts';
|
||||
import { createBackup, restoreBackup } from '../../server/recovery.ts';
|
||||
import { createCoordinatedCustodyBackup, verifyCoordinatedCustodyBackup } from '../../server/coordinated-backup.ts';
|
||||
import { CUSTODY_POLICY, custodyMessage, type CustodyAction, type CustodyCommand, type CustodyActivity,
|
||||
type CustodyListing, type CustodyOrder, type CustodyWithdrawal } from '../../shared/custody.ts';
|
||||
@@ -374,13 +374,22 @@ test('coordinated node/PostgreSQL backup holds both writer fences and verifies m
|
||||
t.after(() => rm(dir, { recursive: true, force: true }));
|
||||
const data = join(dir, 'node-data'), networkDir = join(data, 'testnet');
|
||||
await mkdir(networkDir, { recursive: true });
|
||||
const ledgerDb = new DatabaseSync(join(networkDir, 'ledger.sqlite'));
|
||||
try {
|
||||
ledgerDb.exec(`CREATE TABLE metadata(key TEXT PRIMARY KEY,value TEXT NOT NULL);
|
||||
INSERT INTO metadata VALUES('schema_version','1'),('network','${NETWORK}'),('chain_id','${CHAIN_ID}');
|
||||
CREATE TABLE blocks(sequence INTEGER PRIMARY KEY AUTOINCREMENT,hash TEXT NOT NULL,previous_hash TEXT NOT NULL,block_json TEXT NOT NULL);
|
||||
CREATE TABLE pending_transfers(position INTEGER PRIMARY KEY,id TEXT NOT NULL,transaction_json TEXT NOT NULL);`);
|
||||
} finally { ledgerDb.close(); }
|
||||
const nativeEngine = new RandomX({ binary: process.env.RANDOMX_BINARY });
|
||||
const sourceLedger = await Ledger.open(data, nativeEngine);
|
||||
const blockTemplate = makeTemplate([], {}, seller.actor, seller.publicKey, [], fixtureArticle(56000), fixtureStats(), GENESIS_TIME + 30);
|
||||
const header = structuredClone(blockTemplate.header);
|
||||
let mined: Awaited<ReturnType<typeof nativeEngine.mine>> = null;
|
||||
for (let batch = 0; batch < 16 && !mined; batch++) {
|
||||
mined = await nativeEngine.mine(header.key, miningBlob(header), header.target, 32, 64);
|
||||
if (!mined) header.nonce += 64;
|
||||
}
|
||||
assert.ok(mined, 'Native RandomX cold-backup fixture mining exceeded bounded attempts');
|
||||
header.nonce = mined.nonce;
|
||||
const blockHash = sha256(miningBlob(header));
|
||||
const sourceBlock: TestnetBlock = { ...header, hash: blockHash, tokenId: mintId(header), powHash: mined.hash,
|
||||
signature: seller.sign(blockClaimMessage(blockHash)), transactions: [] };
|
||||
await sourceLedger.submit(sourceBlock);
|
||||
sourceLedger.close(); nativeEngine.close();
|
||||
const marketDb = new DatabaseSync(join(networkDir, 'market.sqlite'));
|
||||
try {
|
||||
marketDb.exec('CREATE TABLE market_meta(key TEXT PRIMARY KEY,value TEXT NOT NULL)');
|
||||
@@ -410,6 +419,14 @@ test('coordinated node/PostgreSQL backup holds both writer fences and verifies m
|
||||
assert.equal(manifest.sqliteCutoverSourceDigest, cutoverDigest);
|
||||
assert.equal((await verifyCoordinatedCustodyBackup(destination)).nodeManifestSha256, manifest.nodeManifestSha256);
|
||||
await assert.rejects(lstat(join(destination, 'node', 'custody-sandbox.sqlite')), { code: 'ENOENT' });
|
||||
const restoredNodeDir = join(dir, 'restored-node');
|
||||
await restoreBackup(join(destination, 'node'), restoredNodeDir);
|
||||
const verifierEngine = new RandomX({ binary: process.env.RANDOMX_BINARY });
|
||||
const verifierLedger = await Ledger.open(restoredNodeDir, verifierEngine);
|
||||
try {
|
||||
assert.equal(verifierLedger.summary().tip, sourceBlock.hash);
|
||||
assert.equal(verifierLedger.nft(sourceBlock.tokenId)?.owner, seller.actor);
|
||||
} finally { verifierLedger.close(); verifierEngine.close(); }
|
||||
const restoreDatabase = `pair_restore_${randomUUID().replaceAll('-', '')}`, run = promisify(execFile);
|
||||
await f.admin.query(`CREATE DATABASE "${restoreDatabase}"`);
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user