diff --git a/components/Settings.vue b/components/Settings.vue index a4a8889..f39ecbd 100644 --- a/components/Settings.vue +++ b/components/Settings.vue @@ -47,51 +47,6 @@ {{ hasErrorRpc.msg }}

-
{{ $t('reset') }} @@ -120,13 +75,9 @@ export default { return { checkingRpc: false, hasErrorRpc: { type: '', msg: '' }, - hasErrorEthRpc: { type: '', msg: '' }, customRpcUrl: '', - customEthUrl: '', selectedRpc: 'custom', - selectedEthRpc: 'custom', - rpc: { name: 'custom', url: '' }, - ethRpc: { name: 'custom', url: '' } + rpc: { name: 'custom', url: '' } } }, computed: { @@ -134,18 +85,9 @@ export default { networkConfig() { return networkConfig[`netId${this.netId}`] }, - ethNetworkConfig() { - return networkConfig.netId1 - }, - isEthereumNetwork() { - return this.netId === 1 - }, isCustomRpc() { return this.selectedRpc === 'custom' }, - isCustomEthRpc() { - return this.selectedEthRpc === 'custom' - }, isDisabledSave() { return ( this.hasErrorRpc.type === 'is-warning' || this.checkingRpc || (this.isCustomRpc && !this.customRpcUrl) @@ -153,24 +95,16 @@ export default { } }, created() { - this.ethRpc = this.getRpc(1) this.rpc = this.getRpc(this.netId) this.selectedRpc = this.rpc.name - this.selectedEthRpc = this.ethRpc.name if (this.selectedRpc === 'custom') { this.$nextTick(() => { this.customRpcUrl = this.rpc.url }) } - if (this.selectedEthRpc === 'custom') { - this.$nextTick(() => { - this.customEthRpcUrl = this.ethRpc.url - }) - } this.checkRpc(this.rpc) - this.checkEthRpc(this.ethRpc) }, methods: { ...mapMutations('settings', ['SAVE_RPC']), @@ -179,40 +113,25 @@ export default { this.hasErrorRpc = { type: '', msg: '' } this.rpc = Object.entries(this.networkConfig.rpcUrls)[0][1] - this.ethRpc = Object.entries(this.ethNetworkConfig.rpcUrls)[0][1] this.selectedRpc = this.rpc.name - this.selectedEthRpc = this.ethRpc.name - this.checkEthRpc(this.ethRpc) this.checkRpc(this.rpc) }, onSave() { this.SAVE_RPC({ ...this.rpc, netId: this.netId }) - if (this.netId !== 1) { - this.SAVE_RPC({ ...this.ethRpc, netId: 1 }) - } this.$emit('close') }, onCancel() { this.$emit('cancel') }, checkRpc({ name, url = '' }) { - this.checkingRpc = true - if (name === 'custom') { this.customRpcUrl = '' this.hasErrorRpc = { type: '', msg: '' } - } - this._checkRpc({ name, url }) - }, - checkEthRpc({ name, url = '' }) { - this.checkingRpc = true - - if (name === 'custom') { - this.customEthRpcUrl = '' - this.hasErrorEthRpc = { type: '', msg: '' } + this.checkingRpc = true return } - this._checkEthRpc({ name, url }) + + this._checkRpc({ name, url }) }, checkCustomRpc(url) { const trimmedUrl = url.trim() @@ -222,14 +141,6 @@ export default { } debounce(this._checkRpc, { name: 'custom', url: trimmedUrl }) }, - checkCustomEthRpc(url) { - const trimmedUrl = url.trim() - if (!trimmedUrl) { - this.hasErrorEthRpc = { type: '', msg: '' } - return - } - debounce(this._checkEthRpc, { name: 'custom', url: trimmedUrl }) - }, async _checkRpc({ name, url }) { this.checkingRpc = true this.hasErrorRpc = { type: '', msg: '' } @@ -248,27 +159,6 @@ export default { this.hasErrorRpc.msg = error } - this.checkingRpc = false - }, - async _checkEthRpc({ name, url }) { - this.checkingRpc = true - this.hasErrorEthRpc = { type: '', msg: '' } - - const { isValid, error } = await this.$store.dispatch('settings/checkRpc', { - url, - netId: 1, - isEthRpc: true - }) - - if (isValid) { - this.hasErrorEthRpc.type = 'is-primary' - this.hasErrorEthRpc.msg = this.$t('rpcStatusOk') - this.ethRpc = { name, url } - } else { - this.hasErrorEthRpc.type = 'is-warning' - this.hasErrorEthRpc.msg = error - } - this.checkingRpc = false } } diff --git a/components/governance/ProposalsList.vue b/components/governance/ProposalsList.vue index 5c02180..1cadbbb 100644 --- a/components/governance/ProposalsList.vue +++ b/components/governance/ProposalsList.vue @@ -59,13 +59,8 @@ export default { } }, computed: { - ...mapState('governance/gov', ['proposals']), - ...mapGetters('governance/gov', [ - 'isFetchingProposals', - 'constants', - 'isFetchingBalances', - 'votingPower' - ]), + ...mapState('governance/gov', ['lockedBalance', 'proposals']), + ...mapGetters('governance/gov', ['isFetchingProposals', 'constants', 'isFetchingBalances']), ...mapGetters('token', ['toDecimals']), filteredProposals() { return this.proposals @@ -79,7 +74,7 @@ export default { }, hasProposalThreshold() { const PROPOSAL_THRESHOLD = toBN(this.constants.PROPOSAL_THRESHOLD) - return toBN(this.votingPower).gte(PROPOSAL_THRESHOLD) + return toBN(this.lockedBalance).gte(PROPOSAL_THRESHOLD) }, proposalThreshold() { return this.toDecimals(this.constants.PROPOSAL_THRESHOLD, 18) diff --git a/networkConfig.js b/networkConfig.js index bdae9c5..31973d8 100644 --- a/networkConfig.js +++ b/networkConfig.js @@ -19,7 +19,7 @@ export default { networkName: 'Ethereum Mainnet', deployedBlock: 9116966, rpcUrls: { - secureRPC: { + SecureRPC: { name: 'SecureRPC', url: 'https://api.securerpc.com/v1' } @@ -135,17 +135,9 @@ export default { multicall: '0x41263cba59eb80dc200f3e2544eda4ed6a90e76c', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', rpcUrls: { - oneRPC: { - name: '1RPC', - url: 'https://1rpc.io/bnb' - }, - blockPi: { - name: 'BlockPi', - url: 'https://bsc.blockpi.network/v1/rpc/public' - }, - nodeReal: { - name: 'NodeReal', - url: 'https://bsc-mainnet.nodereal.io/v1/64a9df0874fb4a93b9d0a3849de012d3' + bscRpc: { + name: 'BSC RPC', + url: 'https://bscrpc.com/' } }, tokens: { @@ -190,13 +182,9 @@ export default { multicall: '0x11ce4B23bD875D7F5C6a31084f55fDe1e9A87507', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', rpcUrls: { - polygonRpc: { + polygonRPC: { name: 'Polygon RPC', - url: 'https://polygon-rpc.com' - }, - oneRpc: { - name: '1RPC', - url: 'https://1rpc.io/matic' + url: `https://polygon-rpc.com` } }, tokens: { @@ -242,17 +230,9 @@ export default { echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', ovmGasPriceOracleContract: '0x420000000000000000000000000000000000000F', rpcUrls: { - blockPi: { - name: 'BlockPi', - url: 'https://optimism.blockpi.network/v1/rpc/public' - }, - oneRpc: { - name: '1RPC', - url: 'https://1rpc.io/op' - }, Optimism: { name: 'Optimism', - url: 'https://mainnet.optimism.io' + url: `https://mainnet.optimism.io` } }, tokens: { @@ -297,13 +277,9 @@ export default { multicall: '0x842eC2c7D803033Edf55E478F461FC547Bc54EB2', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', rpcUrls: { - blockPi: { - name: 'BlockPi', - url: 'https://arbitrum.blockpi.network/v1/rpc/public' - }, Arbitrum: { - name: 'Arbitrum RPC', - url: 'https://arb1.arbitrum.io/rpc' + name: '1RPC', + url: 'https://1rpc.io/arb' } }, tokens: { @@ -348,13 +324,9 @@ export default { multicall: '0xb5b692a88bdfc81ca69dcb1d924f59f0413a602a', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', rpcUrls: { - communityResolver: { - name: 'Community RPC Resolver', + publicRpc: { + name: 'Community RPC', url: 'https://development.tornadocash.community/rpc/v1' - }, - blockPi: { - name: 'BlockPi', - url: 'https://gnosis.blockpi.network/v1/rpc/public' } }, tokens: { @@ -399,21 +371,9 @@ export default { multicall: '0xe86e3989c74293Acc962156cd3F525c07b6a1B6e', echoContractAccount: '0xa75BF2815618872f155b7C4B0C81bF990f5245E4', rpcUrls: { - publicRpc1: { + publicRpc: { name: 'Avalanche RPC', url: 'https://api.avax.network/ext/bc/C/rpc' - }, - blockPi: { - name: 'BlockPi', - url: 'https://avalanche.blockpi.network/v1/rpc/public' - }, - publicRpc2: { - name: 'Avalanche Public PRC', - url: 'https://avalanche-evm.publicnode.com' - }, - oneRpc: { - name: '1RPC', - ulr: 'https://1rpc.io/avax/' } }, tokens: { diff --git a/services/events.js b/services/events.js index 2c0f9bf..7d951f2 100644 --- a/services/events.js +++ b/services/events.js @@ -80,6 +80,7 @@ class EventService { } return a.blockNumber - b.blockNumber }) + const lastBlock = allEvents[allEvents.length - 1].blockNumber this.saveEvents({ events: allEvents, lastBlock, type }) @@ -246,80 +247,87 @@ class EventService { } } - getPastEvents({ fromBlock, toBlock, type }, shouldRetry = false, i = 0) { + getPastEvents({ fromBlock, toBlock, type }) { return new Promise((resolve, reject) => { - this.contract - .getPastEvents(capitalizeFirstLetter(type), { - fromBlock, - toBlock - }) - .then((events) => resolve(events)) - .catch((err) => { - i = i + 1 - // maximum 5 second buffer for rate-limiting - if (shouldRetry) { - const isRetry = i !== 5 + const repsonse = this.contract.getPastEvents(capitalizeFirstLetter(type), { + fromBlock, + toBlock + }) - sleep(1000 * i).then(() => - this.getPastEvents({ fromBlock, toBlock, type }, isRetry, i) - .then((events) => resolve(events)) - .catch((_) => resolve(undefined)) - ) - } else { - reject(new Error(err)) - } - }) + if (repsonse) { + resolve(repsonse) + } else { + reject(new Error()) + } }) } - async getEventsPartFromRpc(parameters, shouldRetry = false) { + async getEventsPartFromRpc({ fromBlock, toBlock, type }, shouldRetry = false, i = 0) { try { - const { fromBlock, type } = parameters const { currentBlockNumber } = await this.getBlocksDiff({ fromBlock }) - if (fromBlock < currentBlockNumber) { - const eventsPart = await this.getPastEvents(parameters, shouldRetry) - - if (eventsPart) { - if (eventsPart.length > 0) { - return { - events: formatEvents(eventsPart, type), - lastBlock: eventsPart[eventsPart.length - 1].blockNumber - } - } else { - return { - events: [], - lastBlock: fromBlock - } - } - } else { - return undefined - } - } else { + if (fromBlock > currentBlockNumber) { return { events: [], lastBlock: fromBlock } } + + let events = [] + + try { + events = await this.getPastEvents({ fromBlock, toBlock, type }) + } catch (e) { + if (shouldRetry) { + i = i + 1 + // maximum 10 second buffer for rate-limiting + await sleep(2000 * i) + + events = await this.getEventsPartFromRpc( + { + fromBlock, + toBlock, + type + }, + i !== 5, + i + ) + } + } + + if (!events?.length) { + return { + events: [], + lastBlock: fromBlock + } + } + return { + events: formatEvents(events, type), + lastBlock: events[events.length - 1].blockNumber + } } catch (err) { return undefined } } - createBatchRequest(batchArray) { - return batchArray.map( - (e, i) => - new Promise((resolve) => - sleep(20 * i).then(() => - this.getEventsPartFromRpc({ ...e }, true).then((batch) => { - if (!batch) { - resolve([{ isFailedBatch: true, ...e }]) - } else { - resolve(batch.events) - } - }) + createBatchRequest({ batchIndex, batchSize, batchBlocks, blockDenom, type }) { + return new Array(batchSize).fill('').map( + (_, i) => + new Promise(async (resolve) => { + const toBlock = batchBlocks[batchIndex * batchSize + i] + const fromBlock = toBlock - blockDenom + + const batchEvents = await this.getEventsPartFromRpc( + { + fromBlock, + toBlock, + type + }, + true ) - ) + + resolve(batchEvents.events) + }) ) } @@ -327,56 +335,38 @@ class EventService { try { const batchSize = 10 const blockRange = 10000 - - let [events, failed] = [[], []] - let lastBlock = fromBlock - const { blockDifference, currentBlockNumber } = await this.getBlocksDiff({ fromBlock }) - const batchDigest = blockDifference === 0 ? 1 : Math.ceil(blockDifference / blockRange) + const batchDigest = blockDifference === 0 ? 1 : Math.ceil(blockDifference / blockRange) const blockDenom = Math.ceil(blockDifference / batchDigest) const batchCount = Math.ceil(batchDigest / batchSize) + const blocks = new Array(batchCount * batchSize).fill('') + const batchBlocks = blocks.map((_, i) => (i + 1) * blockDenom + fromBlock) + + let events = [] + if (fromBlock < currentBlockNumber) { - await this.updateEventProgress(0, type) + this.updateEventProgress(0, type) for (let batchIndex = 0; batchIndex < batchCount; batchIndex++) { - const isLastBatch = batchIndex === batchCount - 1 - const params = new Array(batchSize).fill('').map((_, i) => { - const toBlock = (i + 1) * blockDenom + lastBlock - const fromBlock = toBlock - blockDenom - return { fromBlock, toBlock, type } - }) - const batch = await Promise.all(this.createBatchRequest(params)) - const requests = flattenNArray(batch) + const batch = await Promise.all( + this.createBatchRequest({ batchIndex, batchBlocks, blockDenom, batchSize, type }) + ) - events = events.concat(requests.filter((e) => !e.isFailedBatch)) - failed = failed.concat(requests.filter((e) => e.isFailedBatch)) - lastBlock = params[batchSize - 1].toBlock - - const progressIndex = batchIndex - failed.length / batchSize - - if (isLastBatch && failed.length !== 0) { - const failedBatch = await Promise.all(this.createBatchRequest(failed)) - const failedReqs = flattenNArray(failedBatch) - const failedRept = failedReqs.filter((e) => e.isFailedBatch) - - if (failedRept.length === 0) { - events = events.concat(failedReqs) - } else { - throw new Error('Failed to batch events') - } - } - await this.updateEventProgress(progressIndex / batchCount, type) + this.updateEventProgress(batchIndex / batchCount, type) + events = events.concat(batch) + await sleep(200) } + events = flattenNArray(events) + return { lastBlock: events[events.length - 1].blockNumber, events } - } else { - return undefined } + return undefined } catch (err) { return undefined } diff --git a/services/registry/index.js b/services/registry/index.js index 056224a..c20a744 100644 --- a/services/registry/index.js +++ b/services/registry/index.js @@ -10,7 +10,7 @@ import { sleep, flattenNArray } from '@/utils' import AggregatorABI from '@/abis/Aggregator.abi.json' import RelayerRegistryABI from '@/abis/RelayerRegistry.abi.json' -const MIN_STAKE_BALANCE = '0X1B1AE4D6E2EF500000' // 500 TORN +const MIN_STAKE_BALANCE = '0x22B1C8C1227A00000' // 40 TORN const subdomains = Object.values(networkConfig).map(({ ensSubdomainKey }) => ensSubdomainKey) @@ -28,83 +28,54 @@ class RelayerRegister { fetchEvents = ({ fromBlock, toBlock }, shouldRetry = false) => { return new Promise((resolve, reject) => { if (fromBlock <= toBlock) { - this.relayerRegistry - .getPastEvents('RelayerRegistered', { fromBlock, toBlock }) - .then((events) => resolve(events)) - .catch((_) => { - if (shouldRetry) { - sleep(500).then(() => - this.fetchEvents({ fromBlock, toBlock }) - .then((events) => resolve(events)) - .catch((_) => resolve(undefined)) - ) - } else { - resolve(undefined) - } + try { + const registeredEventsPart = this.relayerRegistry.getPastEvents('RelayerRegistered', { + fromBlock, + toBlock }) + + resolve(registeredEventsPart) + } catch (error) { + if (shouldRetry) { + sleep(1000) + + const events = this.fetchEvents({ fromBlock, toBlock }) + + resolve(events) + } else { + reject(new Error(error)) + } + } } else { - resolve(undefined) + resolve([]) } }) } batchFetchEvents = async ({ fromBlock, toBlock }) => { - const batchSize = 10 const blockRange = 10000 const blockDifference = toBlock - fromBlock const chunkCount = Math.ceil(blockDifference / blockRange) const blockDenom = Math.ceil(blockDifference / chunkCount) - const chunkSize = Math.ceil(chunkCount / batchSize) - let failed = [] - let events = [] - let lastBlock = fromBlock + const promises = new Array(chunkCount).fill('').map( + (_, i) => + new Promise((resolve) => { + sleep(300) - for (let batchIndex = 0; batchIndex < chunkSize; batchIndex++) { - const params = new Array(batchSize).fill('').map((_, i) => { - const toBlock = (i + 1) * blockDenom + lastBlock - const fromBlock = toBlock - blockDenom - return { fromBlock, toBlock } - }) - const promises = new Array(batchSize).fill('').map( - (_, i) => - new Promise((resolve) => - sleep(i * 20).then(() => { - this.fetchEvents(params[i], true).then((batch) => { - if (!batch) { - resolve([{ isFailedBatch: true, fromBlock, toBlock }]) - } else { - resolve(batch) - } - }) - }) + const batch = this.fetchEvents( + { + fromBlock: i * blockDenom + fromBlock, + toBlock: (i + 1) * blockDenom + fromBlock + }, + true ) - ) - const requests = flattenNArray(await Promise.all(promises)) - const failedIndexes = requests - .filter((e) => e.isFailedBatch) - .map((e) => { - const reqIndex = requests.indexOf(e) - return params[reqIndex] + resolve(batch) }) + ) - failed = failed.concat(failedIndexes || []) - events = events.concat(requests.filter((e) => !e.isFailedBatch)) - lastBlock = params[batchSize - 1].toBlock - } - - if (failed.length !== 0) { - const failedReqs = failed.map((e) => this.fetchEvents(e)) - const failedBatch = flattenNArray(await Promise.all(failedReqs)) - - events = events.concat(failedBatch || []) - } - - events = events.map((e) => ({ ...e.returnValues })) - - if (events.length === 0) { - throw new Error('Failed to fetch registry events') - } + const batchEvents = flattenNArray(await Promise.all(promises)) + const events = batchEvents.map((e) => ({ ...e.returnValues })) return events } @@ -199,7 +170,6 @@ class RelayerRegister { for (let x = 0; x < relayerEvents.length; x++) { const { ensName, relayerAddress } = relayerEvents[x] let ensAddress - if (!isAddress(relayerAddress)) { ensAddress = await this.getENSAddress(ensName) ensAddress = toChecksumAddress(ensAddress) diff --git a/store/gasPrices.js b/store/gasPrices.js index 763cd23..8145814 100644 --- a/store/gasPrices.js +++ b/store/gasPrices.js @@ -76,7 +76,7 @@ export const actions = { } catch (e) { console.error('fetchGasPrice', e) } finally { - setTimeout(() => dispatch('fetchGasPrice'), 2000 * pollInterval) + setTimeout(() => dispatch('fetchGasPrice'), 1000 * pollInterval) } }, setDefault({ commit, rootGetters }) { diff --git a/store/governance/gov.js b/store/governance/gov.js index 3d946de..933d6df 100644 --- a/store/governance/gov.js +++ b/store/governance/gov.js @@ -179,35 +179,15 @@ const actions = { ) { try { const { ethAccount } = rootState.metamask - const { lockedBalance, constants, delegators } = state const netId = rootGetters['metamask/netId'] - const proposalThreshold = toBN(constants.PROPOSAL_THRESHOLD) - const proposeIndependently = toBN(lockedBalance).gte(proposalThreshold) - const govInstance = getters.govContract({ netId }) const json = JSON.stringify({ title, description }) - const delegatorAddress = delegators[delegators.length - 1] + const data = await govInstance.methods.propose(proposalAddress, json).encodeABI() - let data, gas - - if (proposeIndependently) { - data = await govInstance.methods.propose(proposalAddress, json).encodeABI() - gas = await govInstance.methods.propose(proposalAddress, json).estimateGas({ - from: ethAccount, - value: 0 - }) - } else { - data = await govInstance.methods - .proposeByDelegate(delegatorAddress, proposalAddress, json) - .encodeABI() - gas = await govInstance.methods - .proposeByDelegate(delegatorAddress, proposalAddress, json) - .estimateGas({ - from: ethAccount, - value: 0 - }) - } + const gas = await govInstance.methods + .propose(proposalAddress, json) + .estimateGas({ from: ethAccount, value: 0 }) const callParams = { method: 'eth_sendTransaction', @@ -708,13 +688,6 @@ const actions = { } } - if (text.includes(`'`)) { - text = text.replaceAll(`'`, `"`) - } - if (text.includes(`" "`)) { - text = text.replace(`" "`, `", "`) - } - let title, description, rest try { ;({ title, description } = JSON.parse(text)) diff --git a/store/settings.js b/store/settings.js index 4b6e7db..94ebe80 100644 --- a/store/settings.js +++ b/store/settings.js @@ -51,14 +51,11 @@ export const actions = { }, async checkCurrentRpc({ dispatch, getters, rootGetters }) { const netId = rootGetters['metamask/netId'] - if (netId !== 1) { - await dispatch('preselectRpc', { netId: 1, isEthRpc: true }) - } await dispatch('preselectRpc', { netId }) }, - async preselectRpc({ getters, commit, dispatch }, { netId, isEthRpc = false }) { + async preselectRpc({ getters, commit, dispatch }, { netId }) { const savedRpc = getters.getRpc(netId) - const { isValid } = await dispatch('checkRpc', { ...savedRpc, netId, isEthRpc }) + const { isValid } = await dispatch('checkRpc', { ...savedRpc, netId }) if (isValid) { return @@ -67,7 +64,7 @@ export const actions = { const { rpcUrls } = networkConfig[`netId${netId}`] for (const [, { name, url }] of Object.entries(rpcUrls)) { - const { isValid, error } = await dispatch('checkRpc', { url, netId, isEthRpc }) + const { isValid, error } = await dispatch('checkRpc', { url, netId }) if (isValid) { commit('SAVE_RPC', { netId, name, url }) return @@ -77,13 +74,14 @@ export const actions = { } throw new Error(this.app.i18n.t('rpcSelectError')) }, - async checkRpc(_, { url, netId, isEthRpc = false }) { + async checkRpc(_, { url, netId }) { try { const web3 = new Web3(url) - const chainId = await web3.eth.getChainId() - const isCurrent = Number(chainId) === Number(netId) - if (isEthRpc || isCurrent) { + const chainId = await web3.eth.getChainId() + + const isCurrent = Number(chainId) === Number(netId) + if (isCurrent) { return { isValid: true } } else { return { isValid: false, error: this.app.i18n.t('thisRpcIsForDifferentNetwork') }