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:
defiQUG
2026-04-12 18:21:05 -07:00
parent 8ec6af94d5
commit 2b52cc6e32
146 changed files with 2010 additions and 423 deletions

View File

@@ -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
};
}
}