refactor(archive): move historical contracts and adapters to archive directory
- Archived multiple non-EVM adapters (Algorand, Hedera, Tron, TON, Cosmos, Solana) and compliance contracts (IndyVerifier) to `archive/solidity/contracts/`. - Updated documentation to reflect the historical status of archived components. - Adjusted `foundry.toml` and `README.md` for clarity on historical dependencies and configurations. - Enhanced Makefile and package.json scripts for improved contract testing and building processes. - Removed obsolete contracts (AlltraCustomBridge, CommodityCCIPBridge, ISO4217WCCIPBridge, VaultBridgeAdapter) from the main directory. - Updated implementation reports to indicate archived status for various components.
This commit is contained in:
@@ -2,15 +2,115 @@
|
||||
* Message Queue for managing pending relay messages
|
||||
*/
|
||||
|
||||
import { mkdir, readFile, rename, writeFile } from 'fs/promises';
|
||||
import path from 'path';
|
||||
|
||||
export class MessageQueue {
|
||||
constructor(logger) {
|
||||
constructor(logger, options = {}) {
|
||||
this.logger = logger;
|
||||
this.persistencePath = options.persistencePath || '';
|
||||
this.queue = [];
|
||||
this.processed = new Set();
|
||||
this.failed = new Set();
|
||||
this.retryCounts = new Map();
|
||||
this.messageStore = new Map();
|
||||
this.inFlight = new Map();
|
||||
this.lastPersistedAt = null;
|
||||
this.persistenceEnabled = Boolean(this.persistencePath);
|
||||
}
|
||||
|
||||
async init() {
|
||||
await this.loadSnapshot();
|
||||
}
|
||||
|
||||
serialize() {
|
||||
return {
|
||||
version: 1,
|
||||
queue: this.queue,
|
||||
retryCounts: Object.fromEntries(this.retryCounts.entries()),
|
||||
savedAt: new Date().toISOString()
|
||||
};
|
||||
}
|
||||
|
||||
static encodeForPersistence(value) {
|
||||
if (typeof value === 'bigint') {
|
||||
return { __type: 'bigint', value: value.toString() };
|
||||
}
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => MessageQueue.encodeForPersistence(item));
|
||||
}
|
||||
if (value && typeof value === 'object') {
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([key, entry]) => [key, MessageQueue.encodeForPersistence(entry)])
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
static decodeFromPersistence(value) {
|
||||
if (Array.isArray(value)) {
|
||||
return value.map((item) => MessageQueue.decodeFromPersistence(item));
|
||||
}
|
||||
if (value && typeof value === 'object') {
|
||||
if (value.__type === 'bigint' && typeof value.value === 'string') {
|
||||
return BigInt(value.value);
|
||||
}
|
||||
return Object.fromEntries(
|
||||
Object.entries(value).map(([key, entry]) => [key, MessageQueue.decodeFromPersistence(entry)])
|
||||
);
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
async persistSnapshot() {
|
||||
if (!this.persistenceEnabled) return;
|
||||
|
||||
const directory = path.dirname(this.persistencePath);
|
||||
const tmpPath = `${this.persistencePath}.tmp`;
|
||||
await mkdir(directory, { recursive: true });
|
||||
await writeFile(
|
||||
tmpPath,
|
||||
JSON.stringify(MessageQueue.encodeForPersistence(this.serialize()), null, 2)
|
||||
);
|
||||
await rename(tmpPath, this.persistencePath);
|
||||
this.lastPersistedAt = new Date().toISOString();
|
||||
}
|
||||
|
||||
async loadSnapshot() {
|
||||
if (!this.persistenceEnabled) return;
|
||||
|
||||
try {
|
||||
const raw = await readFile(this.persistencePath, 'utf8');
|
||||
const parsed = JSON.parse(raw);
|
||||
const restoredQueueRaw = Array.isArray(parsed.queue) ? parsed.queue : [];
|
||||
const restoredQueue = MessageQueue.decodeFromPersistence(restoredQueueRaw);
|
||||
const restoredRetryCounts = parsed.retryCounts && typeof parsed.retryCounts === 'object'
|
||||
? Object.entries(parsed.retryCounts)
|
||||
: [];
|
||||
|
||||
this.queue = restoredQueue;
|
||||
this.messageStore.clear();
|
||||
for (const message of restoredQueue) {
|
||||
if (message?.messageId) {
|
||||
this.messageStore.set(message.messageId, message);
|
||||
}
|
||||
}
|
||||
this.retryCounts = new Map(
|
||||
restoredRetryCounts.map(([messageId, count]) => [messageId, Number(count) || 0])
|
||||
);
|
||||
this.lastPersistedAt = parsed.savedAt || null;
|
||||
|
||||
if (restoredQueue.length > 0) {
|
||||
this.logger.info(
|
||||
`Loaded ${restoredQueue.length} queued relay message(s) from ${this.persistencePath}`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
if (error?.code === 'ENOENT') {
|
||||
return;
|
||||
}
|
||||
this.logger.warn(`Failed to load relay queue snapshot from ${this.persistencePath}`, error);
|
||||
}
|
||||
}
|
||||
|
||||
async add(messageData) {
|
||||
@@ -32,6 +132,7 @@ export class MessageQueue {
|
||||
this.messageStore.set(messageId, messageData);
|
||||
// Add to queue
|
||||
this.queue.push(messageData);
|
||||
await this.persistSnapshot();
|
||||
this.logger.info(`Added message ${messageId} to queue. Queue size: ${this.queue.length}`);
|
||||
}
|
||||
|
||||
@@ -43,6 +144,7 @@ export class MessageQueue {
|
||||
const messageData = this.queue.shift();
|
||||
if (messageData && messageData.messageId) {
|
||||
this.inFlight.set(messageData.messageId, messageData);
|
||||
await this.persistSnapshot();
|
||||
}
|
||||
return messageData;
|
||||
}
|
||||
@@ -52,6 +154,7 @@ export class MessageQueue {
|
||||
this.retryCounts.delete(messageId);
|
||||
this.inFlight.delete(messageId);
|
||||
this.messageStore.delete(messageId);
|
||||
await this.persistSnapshot();
|
||||
this.logger.info(`Message ${messageId} marked as processed`);
|
||||
}
|
||||
|
||||
@@ -59,6 +162,7 @@ export class MessageQueue {
|
||||
this.failed.add(messageId);
|
||||
this.retryCounts.delete(messageId);
|
||||
this.inFlight.delete(messageId);
|
||||
await this.persistSnapshot();
|
||||
this.logger.error(`Message ${messageId} marked as failed`);
|
||||
}
|
||||
|
||||
@@ -68,6 +172,7 @@ export class MessageQueue {
|
||||
|
||||
async resetRetryCount(messageId) {
|
||||
this.retryCounts.delete(messageId);
|
||||
await this.persistSnapshot();
|
||||
}
|
||||
|
||||
async retry(messageId, options = {}) {
|
||||
@@ -75,6 +180,7 @@ export class MessageQueue {
|
||||
const count = this.retryCounts.get(messageId) || 0;
|
||||
if (increment) {
|
||||
this.retryCounts.set(messageId, count + 1);
|
||||
await this.persistSnapshot();
|
||||
}
|
||||
|
||||
const existingIndex = this.queue.findIndex(m => m.messageId === messageId);
|
||||
@@ -92,6 +198,7 @@ export class MessageQueue {
|
||||
|
||||
this.inFlight.delete(messageId);
|
||||
this.queue.push(messageData);
|
||||
await this.persistSnapshot();
|
||||
const nextCount = increment ? count + 1 : count;
|
||||
this.logger.info(`Message ${messageId} requeued. Retry count: ${nextCount}. Queue size: ${this.queue.length}`);
|
||||
}
|
||||
@@ -100,7 +207,9 @@ export class MessageQueue {
|
||||
return {
|
||||
queueSize: this.queue.length,
|
||||
processed: this.processed.size,
|
||||
failed: this.failed.size
|
||||
failed: this.failed.size,
|
||||
persistenceEnabled: this.persistenceEnabled,
|
||||
lastPersistedAt: this.lastPersistedAt
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user