diff --git a/CHANGELOG.md b/CHANGELOG.md index b3b3acbfb..503036727 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - added: (zkSync) Add USDC - added: (Cosmos) Add chain ID updater +- added: (Cosmos) Support multiple archive nodes - fixed: (zkSync) Fix USDC.e currency code ## 4.17.1 (2024-07-30) diff --git a/src/cosmos/CosmosEngine.ts b/src/cosmos/CosmosEngine.ts index f9d924df3..c85b6b9a3 100644 --- a/src/cosmos/CosmosEngine.ts +++ b/src/cosmos/CosmosEngine.ts @@ -522,42 +522,59 @@ export class CosmosEngine extends CurrencyEngine< tokenId => this.allTokensMap[tokenId].currencyCode ) ] - - for (const query of txQueryStrings) { - let startingPage = 1 - let clients = this.getClients() - - if ( - this.networkInfo.archiveNode != null && - Date.now() - TWO_WEEKS > this.otherData.archivedTxLastCheckTime - ) { - startingPage = this.otherData[query].lastPage - clients = await createCosmosClients( - this.fetchCors, - rpcWithApiKey(this.networkInfo.archiveNode, this.tools.initOptions) - ) - } - - const { newestTxid, lastPage } = await this.queryTransactionsInner( - query, - clients, - startingPage + const clientsList: CosmosClients[] = [] + if ( + this.networkInfo.archiveNodes != null && + Date.now() - TWO_WEEKS > this.otherData.archivedTxLastCheckTime + ) { + const sortedArchiveNodes = this.networkInfo.archiveNodes.sort( + (a, b) => a.blockTimeRangeSeconds.start - b.blockTimeRangeSeconds.start ) - if ( - (newestTxid != null && - this.otherData[query]?.newestTxid !== newestTxid) || - lastPage !== this.otherData[query]?.lastPage - ) { - this.otherData[query] = { newestTxid, lastPage } - this.walletLocalDataDirty = true + for (const node of sortedArchiveNodes) { + if ( + node.blockTimeRangeSeconds.end == null || + node.blockTimeRangeSeconds.end > + this.otherData.archivedTxLastCheckTime + ) { + const archiveClients = await createCosmosClients( + this.fetchCors, + rpcWithApiKey(node.endpoint, this.tools.initOptions) + ) + clientsList.push(archiveClients) + } } - progress += 0.5 - allCurrencyCodes.forEach( - code => (this.tokenCheckTransactionsStatus[code] = progress) - ) - this.updateOnAddressesChecked() + } + clientsList.push(this.getClients()) + + for (const clients of clientsList) { + let archivedTxLastCheckTime = 0 + for (const query of txQueryStrings) { + const { newestTxid, lastTimestamp } = await this.queryTransactionsInner( + query, + clients + ) + if ( + newestTxid != null && + this.otherData[query]?.newestTxid !== newestTxid + ) { + this.otherData[query] = { newestTxid } + this.walletLocalDataDirty = true + archivedTxLastCheckTime = Math.max( + archivedTxLastCheckTime, + lastTimestamp + ) + } + progress += 0.5 / clientsList.length + allCurrencyCodes.forEach( + code => (this.tokenCheckTransactionsStatus[code] = progress) + ) + this.updateOnAddressesChecked() + } + this.otherData.archivedTxLastCheckTime = archivedTxLastCheckTime + this.walletLocalDataDirty = true } this.otherData.archivedTxLastCheckTime = Date.now() + this.walletLocalDataDirty = true if (this.transactionsChangedArray.length > 0) { this.currencyEngineCallbacks.onTransactionsChanged( @@ -569,16 +586,16 @@ export class CosmosEngine extends CurrencyEngine< async queryTransactionsInner( queryString: typeof txQueryStrings[number], - clients: CosmosClients, - startingPage: number - ): Promise<{ newestTxid: string | undefined; lastPage: number }> { + clients: CosmosClients + ): Promise<{ newestTxid: string | undefined; lastTimestamp: number }> { const txSearchParams = { query: `${queryString}='${this.walletInfo.keys.bech32Address}'`, per_page: TXS_PER_PAGE, // sdk default 50 order_by: 'asc' } let newestTxid: string | undefined - let page = startingPage + let lastTimestamp = 0 + let page = 1 do { try { const { totalCount, txs } = await clients.cometClient.txSearch({ @@ -641,7 +658,8 @@ export class CosmosEngine extends CurrencyEngine< }) newestTxid = txidHex - this.otherData[queryString] = { newestTxid: txidHex, lastPage: page } + this.otherData[queryString] = { newestTxid: txidHex } + lastTimestamp = date * 1000 this.walletLocalDataDirty = true } @@ -661,11 +679,11 @@ export class CosmosEngine extends CurrencyEngine< } page++ - this.otherData[queryString] = { newestTxid, lastPage: page } + this.otherData[queryString] = { newestTxid } this.walletLocalDataDirty = true } while (true) - return { newestTxid, lastPage: page } + return { newestTxid, lastTimestamp } } processCosmosTransaction( diff --git a/src/cosmos/cosmosTypes.ts b/src/cosmos/cosmosTypes.ts index f563abb69..813a2af46 100644 --- a/src/cosmos/cosmosTypes.ts +++ b/src/cosmos/cosmosTypes.ts @@ -79,7 +79,14 @@ export interface CosmosNetworkInfo { nativeDenom: string pluginMnemonicKeyName: string rpcNode: HttpEndpoint - archiveNode?: HttpEndpoint // If no archive node, the rpc node will be used and only grab transaction in a limited range + // If no archive node, the rpc node will be used and only grab transaction in a limited range + archiveNodes?: Array<{ + blockTimeRangeSeconds: { + start: number + end?: number + } + endpoint: HttpEndpoint + }> } const asHttpEndpoint = asObject({ url: asString, @@ -92,19 +99,16 @@ export const txQueryStrings = [ ] as const const asLocalTxQueryParams = asObject({ - newestTxid: asMaybe(asString), - lastPage: asMaybe(asNumber, 1) + newestTxid: asMaybe(asString) }) export const asCosmosWalletOtherData = asObject({ archivedTxLastCheckTime: asMaybe(asNumber, 0), 'coin_spent.spender': asMaybe(asLocalTxQueryParams, () => ({ - newestTxid: undefined, - lastPage: 1 + newestTxid: undefined })), 'coin_received.receiver': asMaybe(asLocalTxQueryParams, () => ({ - newestTxid: undefined, - lastPage: 1 + newestTxid: undefined })) }) export type CosmosWalletOtherData = ReturnType @@ -274,7 +278,7 @@ export interface IbcChannel { export const asCosmosInfoPayload = asObject({ rpcNode: asOptional(asHttpEndpoint), - archiveNode: asOptional(asHttpEndpoint) + archiveNodes: asOptional(asHttpEndpoint) }) export type CosmosInfoPayload = ReturnType diff --git a/src/cosmos/info/axelarInfo.ts b/src/cosmos/info/axelarInfo.ts index 493da4bfc..a8eee28c7 100644 --- a/src/cosmos/info/axelarInfo.ts +++ b/src/cosmos/info/axelarInfo.ts @@ -22,10 +22,17 @@ const networkInfo: CosmosNetworkInfo = { url: 'https://axelar-rpc.publicnode.com:443', headers: {} }, - archiveNode: { - url: 'https://axelararchive-rpc.quickapi.com:443', - headers: {} - } + archiveNodes: [ + { + blockTimeRangeSeconds: { + start: 0 + }, + endpoint: { + url: 'https://axelararchive-rpc.quickapi.com:443', + headers: {} + } + } + ] } const currencyInfo: EdgeCurrencyInfo = { diff --git a/src/cosmos/info/coreumInfo.ts b/src/cosmos/info/coreumInfo.ts index c81e5a316..de9e95ba3 100644 --- a/src/cosmos/info/coreumInfo.ts +++ b/src/cosmos/info/coreumInfo.ts @@ -143,10 +143,17 @@ const networkInfo: CosmosNetworkInfo = { url: 'https://full-node.mainnet-1.coreum.dev:26657', headers: {} }, - archiveNode: { - url: 'https://full-node.mainnet-1.coreum.dev:26657', - headers: {} - } + archiveNodes: [ + { + blockTimeRangeSeconds: { + start: 0 + }, + endpoint: { + url: 'https://full-node.mainnet-1.coreum.dev:26657', + headers: {} + } + } + ] } const currencyInfo: EdgeCurrencyInfo = { diff --git a/src/cosmos/info/osmosisInfo.ts b/src/cosmos/info/osmosisInfo.ts index fc68c292d..0a805bc89 100644 --- a/src/cosmos/info/osmosisInfo.ts +++ b/src/cosmos/info/osmosisInfo.ts @@ -35,10 +35,17 @@ const networkInfo: CosmosNetworkInfo = { url: 'https://rpc.osmosis.zone:443', headers: {} }, - archiveNode: { - url: 'https://osmosisarchive-rpc.quickapi.com:443', - headers: {} - } + archiveNodes: [ + { + blockTimeRangeSeconds: { + start: 0 + }, + endpoint: { + url: 'https://osmosisarchive-rpc.quickapi.com:443', + headers: {} + } + } + ] } const currencyInfo: EdgeCurrencyInfo = { diff --git a/src/cosmos/info/thorchainruneInfo.ts b/src/cosmos/info/thorchainruneInfo.ts index c175f1241..f1cd7b6d2 100644 --- a/src/cosmos/info/thorchainruneInfo.ts +++ b/src/cosmos/info/thorchainruneInfo.ts @@ -28,10 +28,27 @@ const networkInfo: CosmosNetworkInfo = { url: 'https://rpc.ninerealms.com', headers: { 'x-client-id': '{{ninerealmsClientId}}' } }, - archiveNode: { - url: 'https://rpc-v1.ninerealms.com', - headers: { 'x-client-id': '{{ninerealmsClientId}}' } - } + archiveNodes: [ + { + blockTimeRangeSeconds: { + start: 1647912564649 // 2022-03-22T01:29:24.649Z + // end: TBD + }, + endpoint: { + url: 'https://rpc-v1.ninerealms.com', + headers: { 'x-client-id': '{{ninerealmsClientId}}' } + } + } + // { + // blockTimeRangeSeconds: { + // start: TBD + // }, + // endpoint: { + // url: 'https://rpc-v2.ninerealms.com', + // headers: { 'x-client-id': '{{ninerealmsClientId}}' } + // } + // } + ] } const currencyInfo: EdgeCurrencyInfo = {