Initial commit
This commit is contained in:
148
src/infrastructure/sovereign-cloud/sci-replication.service.ts
Normal file
148
src/infrastructure/sovereign-cloud/sci-replication.service.ts
Normal file
@@ -0,0 +1,148 @@
|
||||
// SCI Replication Service
|
||||
// Global Replication Grid (GRG) with 30s metadata hashing
|
||||
|
||||
import prisma from '@/shared/database/prisma';
|
||||
import { createHash } from 'crypto';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { logger } from '@/infrastructure/monitoring/logger';
|
||||
|
||||
|
||||
const METADATA_HASH_INTERVAL = 30000; // 30 seconds
|
||||
|
||||
export interface ReplicationRequest {
|
||||
zoneId: string;
|
||||
targetZoneId: string;
|
||||
replicationType: 'metadata' | 'full' | 'incremental';
|
||||
}
|
||||
|
||||
export class SciReplicationService {
|
||||
private hashIntervals: Map<string, NodeJS.Timeout> = new Map();
|
||||
|
||||
/**
|
||||
* Start replication between zones
|
||||
*/
|
||||
async startReplication(request: ReplicationRequest): Promise<{ replicationId: string }> {
|
||||
const replicationId = `REP-${uuidv4()}`;
|
||||
|
||||
// Create replication record
|
||||
await prisma.sovereignReplication.create({
|
||||
data: {
|
||||
replicationId,
|
||||
zoneId: request.zoneId,
|
||||
targetZoneId: request.targetZoneId,
|
||||
replicationType: request.replicationType,
|
||||
metadataHash: '',
|
||||
lastHashTime: new Date(),
|
||||
status: 'active',
|
||||
},
|
||||
});
|
||||
|
||||
// Start metadata hashing interval
|
||||
this.startMetadataHashing(replicationId, request.zoneId);
|
||||
|
||||
logger.info('SCI: Started replication', {
|
||||
replicationId,
|
||||
zoneId: request.zoneId,
|
||||
targetZoneId: request.targetZoneId,
|
||||
replicationType: request.replicationType,
|
||||
});
|
||||
|
||||
return { replicationId };
|
||||
}
|
||||
|
||||
/**
|
||||
* Start metadata hashing every 30 seconds
|
||||
*/
|
||||
private startMetadataHashing(replicationId: string, zoneId: string): void {
|
||||
const interval = setInterval(async () => {
|
||||
try {
|
||||
await this.updateMetadataHash(replicationId, zoneId);
|
||||
} catch (error) {
|
||||
logger.error('SCI: Metadata hashing failed', { error, replicationId, zoneId });
|
||||
}
|
||||
}, METADATA_HASH_INTERVAL);
|
||||
|
||||
this.hashIntervals.set(replicationId, interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update metadata hash
|
||||
*/
|
||||
private async updateMetadataHash(replicationId: string, zoneId: string): Promise<void> {
|
||||
// Get zone metadata
|
||||
const zone = await prisma.sovereignComputeZone.findUnique({
|
||||
where: { zoneId },
|
||||
include: {
|
||||
contracts: true,
|
||||
attestations: {
|
||||
where: { status: 'verified' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (!zone) {
|
||||
throw new Error('Zone not found');
|
||||
}
|
||||
|
||||
// Create metadata object
|
||||
const metadata = {
|
||||
zoneId: zone.zoneId,
|
||||
status: zone.status,
|
||||
contractCount: zone.contracts.length,
|
||||
verifiedAttestationCount: zone.attestations.length,
|
||||
timestamp: new Date().toISOString(),
|
||||
};
|
||||
|
||||
// Calculate hash
|
||||
const metadataString = JSON.stringify(metadata);
|
||||
const metadataHash = createHash('sha256').update(metadataString).digest('hex');
|
||||
|
||||
// Update replication record
|
||||
await prisma.sovereignReplication.update({
|
||||
where: { replicationId },
|
||||
data: {
|
||||
metadataHash,
|
||||
lastHashTime: new Date(),
|
||||
},
|
||||
});
|
||||
|
||||
logger.debug('SCI: Updated metadata hash', { replicationId, metadataHash });
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop replication
|
||||
*/
|
||||
async stopReplication(replicationId: string): Promise<void> {
|
||||
// Stop hashing interval
|
||||
const interval = this.hashIntervals.get(replicationId);
|
||||
if (interval) {
|
||||
clearInterval(interval);
|
||||
this.hashIntervals.delete(replicationId);
|
||||
}
|
||||
|
||||
// Update replication status
|
||||
await prisma.sovereignReplication.update({
|
||||
where: { replicationId },
|
||||
data: { status: 'paused' },
|
||||
});
|
||||
|
||||
logger.info('SCI: Stopped replication', { replicationId });
|
||||
}
|
||||
|
||||
/**
|
||||
* Get replication status
|
||||
*/
|
||||
async getReplicationStatus(replicationId: string) {
|
||||
const replication = await prisma.sovereignReplication.findUnique({
|
||||
where: { replicationId },
|
||||
include: {
|
||||
zone: true,
|
||||
},
|
||||
});
|
||||
|
||||
return replication;
|
||||
}
|
||||
}
|
||||
|
||||
export const sciReplicationService = new SciReplicationService();
|
||||
|
||||
Reference in New Issue
Block a user