Skip to content

Commit

Permalink
Merge pull request #867 from telosnetwork/860-the-transaction-tab-on-…
Browse files Browse the repository at this point in the history
…the-address-page-still-makes-a-separate-query-to-get-possible-contract-metadata-for-each-address

#860 | Contract Manager improvement
  • Loading branch information
pmjanus authored Nov 5, 2024
2 parents ed7b70d + 642c69e commit 3300def
Showing 1 changed file with 29 additions and 75 deletions.
104 changes: 29 additions & 75 deletions src/lib/contract/ContractManager.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,10 @@ const tokenList = 'https://raw.githubusercontent.com/telosnetwork/token-list/mai
const systemContractList =
'https://raw.githubusercontent.com/telosnetwork/token-list/main/telosevm.systemcontractlist.json';


class AddressCacheManager {
constructor() {
this.addressesByNetwork = {};
this.contractInfoByNetwork = {};
this.maxAddresses = 1000;
this.loadFromLocalStorage();
}

Expand All @@ -22,37 +21,16 @@ class AddressCacheManager {
}

loadFromLocalStorage() {
const storedAddresses = localStorage.getItem('noContractAddressesByNetwork');
const storedContractInfo = localStorage.getItem('contractInfoByNetwork');
if (storedAddresses) {
this.addressesByNetwork = JSON.parse(storedAddresses);
}
if (storedContractInfo) {
this.contractInfoByNetwork = JSON.parse(storedContractInfo);
}
}

saveToLocalStorage() {
localStorage.setItem('noContractAddressesByNetwork', JSON.stringify(this.addressesByNetwork));
localStorage.setItem('contractInfoByNetwork', JSON.stringify(this.contractInfoByNetwork));
}

addNullAddress(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
if (!this.addressesByNetwork[network]) {
this.addressesByNetwork[network] = [];
}

if (!this.exists(addressLower)) {
this.addressesByNetwork[network].push(addressLower);
if (this.addressesByNetwork[network].length > this.maxAddresses) {
this.addressesByNetwork[network] = this.addressesByNetwork[network].slice(-this.maxAddresses);
}
this.saveToLocalStorage();
}
}

addContractInfo(address, name, symbol = null) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
Expand All @@ -66,14 +44,6 @@ class AddressCacheManager {
this.contractInfoByNetwork[network][addressLower] = info;
this.saveToLocalStorage();
}

this.removeNullAddress(address);
}

exists(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
return this.addressesByNetwork[network] && this.addressesByNetwork[network].includes(addressLower);
}

existsContract(address) {
Expand All @@ -82,37 +52,12 @@ class AddressCacheManager {
return this.contractInfoByNetwork[network] && this.contractInfoByNetwork[network][addressLower];
}

removeNullAddress(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
if (this.addressesByNetwork[network]) {
const index = this.addressesByNetwork[network].indexOf(addressLower);
if (index !== -1) {
this.addressesByNetwork[network].splice(index, 1);
this.saveToLocalStorage();
}
}
}

getAddresses() {
const network = this.getCurrentNetwork();
return this.addressesByNetwork[network] ? [...this.addressesByNetwork[network]] : [];
}

getContractInfo(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
const network = this.getCurrentNetwork();
return this.contractInfoByNetwork[network] ? this.contractInfoByNetwork[network][addressLower] : null;
}

clearAddresses() {
const network = this.getCurrentNetwork();
if (this.addressesByNetwork[network]) {
this.addressesByNetwork[network] = [];
this.saveToLocalStorage();
}
}

clearContractInfo() {
const network = this.getCurrentNetwork();
if (this.contractInfoByNetwork[network]) {
Expand Down Expand Up @@ -141,10 +86,7 @@ export default class ContractManager {
if (!this.contracts[network]) {
this.contracts[network] = {};
}
if (this.nullContractsManager.exists(address)) {
return null;
}
return this.contracts[network][address.toLowerCase()];
return this.contracts[network][address.toLowerCase()] || null;
}

setNetworkContract(address, contract) {
Expand All @@ -153,9 +95,7 @@ export default class ContractManager {
this.contracts[network] = {};
}
this.contracts[network][address.toLowerCase()] = contract;
if (contract === null) {
this.nullContractsManager.addNullAddress(address);
} else {
if (contract) {
this.nullContractsManager.addContractInfo(address, contract.name, contract.properties?.symbol || null);
}
}
Expand Down Expand Up @@ -381,27 +321,21 @@ export default class ContractManager {
}
async getContractDisplayInfo(address) {
const addressLower = typeof address === 'string' ? address.toLowerCase() : '';
let result;
if (this.nullContractsManager.exists(addressLower)) {
result = null;
} else if (this.nullContractsManager.existsContract(addressLower)) {
result = this.nullContractsManager.getContractInfo(addressLower);
if (this.nullContractsManager.existsContract(addressLower)) {
return this.nullContractsManager.getContractInfo(addressLower);
} else {
// We are going to always assume that if the address is a contract, it is already in the cache
// Because the indexer API should always return all involved contracts in a query response
return null;
}
return result;
}
async getContract(address, force) {
async getContractForced(address) {
if (address === null || typeof address !== 'string') {
return;
}
const addressLower = address.toLowerCase();

if (!force && typeof this.getNetworkContract(addressLower) !== 'undefined') {
return this.getNetworkContract(addressLower);
}

// if this function is repeatedly called for the same address, wait for the first call to finish
if (this.processing.includes(addressLower)) {
await new Promise(resolve => setTimeout(resolve, 300));
return await this.getNetworkContract(addressLower);
Expand Down Expand Up @@ -430,8 +364,28 @@ export default class ContractManager {
if(index > -1){
this.processing.splice(index, 1);
}
return this.factory.buildContract(contract);
return this.getContract(address);
}

async getContract(address, force) {
if (address === null || typeof address !== 'string') {
return null;
}

if (force) {
return await this.getContractForced(address);
}

const addressLower = address.toLowerCase();

const cashedContract = this.getNetworkContract(addressLower);
if (!force && cashedContract) {
return cashedContract;
}

return null;
}

async getContractFromAbi(address, abi){
return new ethers.Contract(address, abi, this.getEthersProvider());
}
Expand Down

0 comments on commit 3300def

Please sign in to comment.