Custodial financial storage
This commit is contained in:
@@ -30,6 +30,9 @@ function inspect(file:string,name:typeof files[number]) {
|
||||
const meta=(key:string)=>(db.prepare('SELECT value FROM metadata WHERE key=?').get(key) as {value:string}|undefined)?.value;
|
||||
if(meta('schema_version')!=='1'||meta('network')!==NETWORK||meta('chain_id')!==CHAIN_ID)throw new Error('Ledger network/schema mismatch');
|
||||
}else if(name==='custody-sandbox.sqlite'){
|
||||
if(db.prepare("SELECT 1 FROM custody_meta WHERE key='postgres_cutover'").get()) {
|
||||
throw new Error('PostgreSQL cutover source cannot be backed up as current custody; coordinated database backup required');
|
||||
}
|
||||
const row=db.prepare("SELECT value FROM custody_meta WHERE key='identity'").get() as {value:string}|undefined;
|
||||
const identity=row?JSON.parse(row.value):undefined;
|
||||
if(identity?.version!==1||identity.network!==NETWORK||identity.chainId!==CHAIN_ID||identity.mode!=='sandbox'||
|
||||
@@ -53,6 +56,9 @@ export async function createBackup(dataDir:string,destination:string){
|
||||
const rel=relative(source,dest);
|
||||
if(!rel||(!rel.startsWith('..')&&!isAbsolute(rel)))throw new Error('Backup destination must be outside the node data directory');
|
||||
return offlineLock(source,async()=>{
|
||||
// File-only backups cannot represent an external financial database. Fail rather than omit liabilities.
|
||||
try { await lstat(join(source,PROFILE,'custody-postgres.json')); throw new Error('PostgreSQL custody requires coordinated database and node backup; SQLite-only backup refused'); }
|
||||
catch(e) { if ((e as NodeJS.ErrnoException).code !== 'ENOENT') throw e; }
|
||||
if(await realpath(join(source,PROFILE))!==join(source,PROFILE))throw new Error('Network data directory must not be symlinked');
|
||||
await mkdir(dest,{mode:0o700}); // Exclusive: never overwrite or recursively create a surprising destination.
|
||||
const entries=[];
|
||||
|
||||
Reference in New Issue
Block a user