Skip to content

Commit

Permalink
Merge pull request #125 from eco-stake/improve-api-errors
Browse files Browse the repository at this point in the history
Reduce API errors
  • Loading branch information
tombeynon authored Jan 15, 2025
2 parents 66ecc79 + b27f2ff commit 407a39b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 53 deletions.
4 changes: 2 additions & 2 deletions src/components/Voting.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,12 +83,12 @@ function Voting(props) {
const { clearExisting } = opts || {}

try {
let newProposals = await network.restClient.getProposals()
let newProposals = await network.restClient.getProposals({ timeout: 10000 })
newProposals = await mapSync(newProposals.map(el => {
return async () => {
return await Proposal(el)
}
}))
}), 5)

setError()
setProposals(sortProposals(newProposals))
Expand Down
3 changes: 1 addition & 2 deletions src/utils/Network.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,9 @@ class Network {
this.gasModifier = this.data.gasModifier || 1.5
}

async connect(opts) {
async connect() {
try {
this.restClient = await RestClient(this.chain.chainId, this.restUrl, {
connectTimeout: opts?.timeout,
apiVersions: this.chain.apiVersions
})
this.restUrl = this.restClient.restUrl
Expand Down
9 changes: 6 additions & 3 deletions src/utils/Proposal.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@ const Proposal = async (data) => {
}else{
ipfsUrl = `https://ipfs.io/ipfs/${metadata}`
}
metadata = await axios.get(ipfsUrl, { timeout: 5000 }).then(res => res.data)
title = metadata.title
description = metadata.summary || metadata.description || metadata.details
response = await axios.get(ipfsUrl, { timeout: 5000 })
if(response.headers['content-type'] === 'application/json'){
metadata = response.data
title = metadata.title
description = metadata.summary || metadata.description || metadata.details
}
} catch (e) {
console.log(e)
}
Expand Down
99 changes: 53 additions & 46 deletions src/utils/RestClient.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ import { sleep } from "@cosmjs/utils";

const RestClient = async (chainId, restUrls, opts) => {
const config = _.merge({
connectTimeout: 10000,
timeout: 5000,
retries: 2,
apiVersions: {}
}, opts)
const restUrl = await findAvailableUrl(restUrls, { timeout: config.connectTimeout })
const restUrl = await findAvailableUrl(restUrls, { timeout: 10000 })
const client = axios.create({ baseURL: restUrl, timeout: config.timeout });
axiosRetry(client, { retries: config.retries, shouldResetTimeout: true, retryCondition: () => true });

function getAllValidators(pageSize, opts, pageCallback) {
return getAllPages((nextKey) => {
Expand All @@ -33,9 +37,9 @@ const RestClient = async (chainId, restUrls, opts) => {
searchParams.append("pagination.limit", pageSize);
if (nextKey)
searchParams.append("pagination.key", nextKey);
return axios
return client
.get(
apiUrl('staking', `validators?${searchParams.toString()}`), {
apiPath('staking', `validators?${searchParams.toString()}`), {
timeout: opts.timeout || 10000,
})
.then((res) => res.data);
Expand All @@ -59,8 +63,8 @@ const RestClient = async (chainId, restUrls, opts) => {
if (nextKey)
searchParams.append("pagination.key", nextKey);

return axios
.get(apiUrl('staking', `validators/${validatorAddress}/delegations?${searchParams.toString()}`), opts)
return client
.get(apiPath('staking', `validators/${validatorAddress}/delegations?${searchParams.toString()}`), opts)
.then((res) => res.data);
}

Expand All @@ -69,8 +73,8 @@ const RestClient = async (chainId, restUrls, opts) => {
const searchParams = new URLSearchParams();
if (nextKey)
searchParams.append("pagination.key", nextKey);
return axios
.get(apiUrl('bank', `balances/${address}?${searchParams.toString()}`), opts)
return client
.get(apiPath('bank', `balances/${address}?${searchParams.toString()}`), opts)
.then((res) => res.data)
}).then((pages) => {
const result = pages.map((el) => el.balances).flat()
Expand All @@ -85,8 +89,8 @@ const RestClient = async (chainId, restUrls, opts) => {
}

function getDelegations(address) {
return axios
.get(apiUrl('staking', `delegations/${address}`))
return client
.get(apiPath('staking', `delegations/${address}`))
.then((res) => res.data)
.then((result) => {
const delegations = result.delegation_responses.reduce(
Expand All @@ -98,8 +102,8 @@ const RestClient = async (chainId, restUrls, opts) => {
}

function getRewards(address, opts) {
return axios
.get(apiUrl('distribution', `delegators/${address}/rewards`), opts)
return client
.get(apiPath('distribution', `delegators/${address}/rewards`), opts)
.then((res) => res.data)
.then((result) => {
const rewards = result.rewards.reduce(
Expand All @@ -111,8 +115,8 @@ const RestClient = async (chainId, restUrls, opts) => {
}

function getCommission(validatorAddress, opts) {
return axios
.get(apiUrl('distribution', `validators/${validatorAddress}/commission`), opts)
return client
.get(apiPath('distribution', `validators/${validatorAddress}/commission`), opts)
.then((res) => res.data)
.then((result) => {
return result.commission;
Expand All @@ -127,23 +131,23 @@ const RestClient = async (chainId, restUrls, opts) => {
if (nextKey)
searchParams.append("pagination.key", nextKey);

return axios
.get(apiUrl('gov', `proposals?${searchParams.toString()}`), opts)
return client
.get(apiPath('gov', `proposals?${searchParams.toString()}`), opts)
.then((res) => res.data);
}).then((pages) => {
return pages.map(el => el.proposals).flat();
});
}

function getProposalTally(proposal_id, opts) {
return axios
.get(apiUrl('gov', `proposals/${proposal_id}/tally`), opts)
return client
.get(apiPath('gov', `proposals/${proposal_id}/tally`), opts)
.then((res) => res.data);
}

function getProposalVote(proposal_id, address, opts) {
return axios
.get(apiUrl('gov', `proposals/${proposal_id}/votes/${address}`), opts)
return client
.get(apiPath('gov', `proposals/${proposal_id}/votes/${address}`), opts)
.then((res) => res.data);
}

Expand All @@ -155,8 +159,8 @@ const RestClient = async (chainId, restUrls, opts) => {
if (nextKey)
searchParams.append("pagination.key", nextKey);

return axios
.get(apiUrl('authz', `grants/grantee/${grantee}?${searchParams.toString()}`), opts)
return client
.get(apiPath('authz', `grants/grantee/${grantee}?${searchParams.toString()}`), opts)
.then((res) => res.data);
}, pageCallback).then((pages) => {
return pages.map(el => el.grants).flat();
Expand All @@ -171,8 +175,8 @@ const RestClient = async (chainId, restUrls, opts) => {
if (nextKey)
searchParams.append("pagination.key", nextKey);

return axios
.get(apiUrl('authz', `grants/granter/${granter}?${searchParams.toString()}`), opts)
return client
.get(apiPath('authz', `grants/granter/${granter}?${searchParams.toString()}`), opts)
.then((res) => res.data);
}, pageCallback).then((pages) => {
return pages.map(el => el.grants).flat();
Expand All @@ -185,17 +189,17 @@ const RestClient = async (chainId, restUrls, opts) => {
searchParams.append("grantee", grantee);
if (granter)
searchParams.append("granter", granter);
return axios
.get(apiUrl('authz', `grants?${searchParams.toString()}`), opts)
return client
.get(apiPath('authz', `grants?${searchParams.toString()}`), opts)
.then((res) => res.data)
.then((result) => {
return result.grants;
});
}

function getWithdrawAddress(address, opts) {
return axios
.get(apiUrl('distribution', `delegators/${address}/withdraw_address`))
return client
.get(apiPath('distribution', `delegators/${address}/withdraw_address`))
.then((res) => res.data)
.then((result) => {
return result.withdraw_address;
Expand All @@ -214,18 +218,23 @@ const RestClient = async (chainId, restUrls, opts) => {
}
if (order)
searchParams.append('order_by', order);
const client = axios.create({ baseURL: restUrl });
axiosRetry(client, { retries: retries || 0, shouldResetTimeout: true, retryCondition: (e) => true });
return client.get(apiPath('tx', `txs?${searchParams.toString()}`), opts).then((res) => res.data);
return client.get(apiPath('tx', `txs?${searchParams.toString()}`), {
'axios-retry': { retries: retries ?? config.retries },
...opts
}).then((res) => res.data);
}

function getTransaction(txHash) {
return axios.get(apiUrl('tx', `txs/${txHash}`)).then((res) => res.data);
function getTransaction(txHash, _opts) {
const { retries, ...opts } = _opts;
return client.get(apiPath('tx', `txs/${txHash}`), {
'axios-retry': { retries: retries ?? config.retries },
...opts
}).then((res) => res.data);
}

function getAccount(address) {
return axios
.get(apiUrl('auth', `accounts/${address}`))
return client
.get(apiPath('auth', `accounts/${address}`))
.then((res) => res.data.account)
.then((value) => {
if(!value) throw new Error('Failed to fetch account, please try again')
Expand Down Expand Up @@ -275,12 +284,12 @@ const RestClient = async (chainId, restUrls, opts) => {
};

function simulate(params){
return axios.post(apiUrl('tx', `simulate`), params)
return client.post(apiPath('tx', `simulate`), params, { timeout: 30000 })
.then((res) => res.data)
}

function broadcast(params){
return axios.post(apiUrl('tx', `txs`), params)
return client.post(apiPath('tx', `txs`), params, { timeout: 30000, 'axios-retry': { retries: 0 } })
.then((res) => parseTxResult(res.data.tx_response))
}

Expand All @@ -300,7 +309,7 @@ const RestClient = async (chainId, restUrls, opts) => {
}
await sleep(pollIntervalMs);
try {
const response = await getTransaction(txId);
const response = await getTransaction(txId, { retries: 0 });
const result = parseTxResult(response.tx_response)
return result
} catch {
Expand Down Expand Up @@ -370,10 +379,13 @@ const RestClient = async (chainId, restUrls, opts) => {

async function getLatestBlock(opts){
const { timeout } = opts || {}
const url = opts?.url || restUrl
let blockClient = client
if(opts?.url){
blockClient = axios.create({ baseURL: opts.url });
}
const path = opts?.path || apiPath('/base/tendermint', 'blocks/latest')
try {
return await axios.get(url + path, { timeout })
return await blockClient.get(path, { timeout })
.then((res) => res.data)
} catch (error) {
const fallback = '/blocks/latest'
Expand All @@ -384,13 +396,8 @@ const RestClient = async (chainId, restUrls, opts) => {
}
}

function apiUrl(type, path){
return restUrl + apiPath(type, path)
}

function apiPath(type, path){
const versions = config.apiVersions || {}
const version = versions[type] || 'v1beta1'
const version = config.apiVersions[type] || 'v1beta1'
return `/cosmos/${type}/${version}/${path}`
}

Expand Down

0 comments on commit 407a39b

Please sign in to comment.