Skip to content

Commit

Permalink
Merge pull request #906 from Giveth/feat/add_origin_header_rpc_node_q…
Browse files Browse the repository at this point in the history
…ueries

Add Origin header to node rpc queries + remove web3js dependency
  • Loading branch information
mohammadranjbarz authored Mar 15, 2023
2 parents 163793c + 360bda0 commit 740bc39
Show file tree
Hide file tree
Showing 10 changed files with 10,144 additions and 14,418 deletions.
5 changes: 5 additions & 0 deletions config/example.env
Original file line number Diff line number Diff line change
Expand Up @@ -163,3 +163,8 @@ CHAINVINE_API_ENABLE_TEST_MODE=true

# We should not try to verify donaitons after some hours, because checking old donations would make lots of requests to web3 providers
DONATION_VERIFICAITON_EXPIRATION_HOURS=24


# OPTIONAL - This is the name of the service, it should be unique to monitor RPC node usage
# Default: unnamed
SERVICE_NAME=example
24,342 changes: 10,042 additions & 14,300 deletions package-lock.json

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@
"cors": "^2.8.5",
"dotenv": "^8.2.0",
"eth-sig-util": "^3.0.1",
"ethers": "^5.5.4",
"ethers": "^5.7.2",
"express": "^4.17.1",
"express-formidable": "^1.2.0",
"express-rate-limit": "^5.5.1",
Expand Down Expand Up @@ -76,8 +76,7 @@
"type-graphql": "2.0.0-beta.1",
"typedi": "0.8.0",
"typeorm": "0.3.11",
"typescript": "^4.9.4",
"web3": "1.7.5"
"typescript": "^4.9.4"
},
"lint-staged": {
"*.ts": [
Expand Down
62 changes: 25 additions & 37 deletions src/provider.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import config from './config';
import { ethers } from 'ethers';
import Web3 from 'web3';
import {
errorMessages,
i18n,
translationErrorMessagesKeys,
} from './utils/errorMessages';
import { i18n, translationErrorMessagesKeys } from './utils/errorMessages';

const INFURA_API_KEY = config.get('INFURA_API_KEY');

Expand Down Expand Up @@ -95,49 +90,42 @@ export function getNetworkNativeToken(networkId: number): string {
return networkInfo.nativeToken;
}

const mainnetNodeUrl = `https://${NETWORK_NAMES.MAINNET}.infura.io/v3/${INFURA_API_KEY}`;
const mainnetWeb3 = new Web3(mainnetNodeUrl);
const ropstenNodeUrl = `https://${NETWORK_NAMES.ROPSTEN}.infura.io/v3/${INFURA_API_KEY}`;
const ropstenWeb3 = new Web3(ropstenNodeUrl);
const goerliNodeUrl = `https://${NETWORK_NAMES.GOERLI}.infura.io/v3/${INFURA_API_KEY}`;
const goerliWeb3 = new Web3(goerliNodeUrl);
const polygonNodeUrl = `https://${NETWORK_NAMES.POLYGON}.infura.io/v3/${INFURA_API_KEY}`;
const polygonWeb3 = new Web3(polygonNodeUrl);
const xdaiWeb3NodeUrl = config.get('XDAI_NODE_HTTP_URL') as string;
const xdaiWeb3 = new Web3(xdaiWeb3NodeUrl);

export const getNetworkWeb3 = (networkId: number): Web3 => {
switch (networkId) {
case NETWORK_IDS.MAIN_NET:
return mainnetWeb3;
case NETWORK_IDS.ROPSTEN:
return ropstenWeb3;
case NETWORK_IDS.GOERLI:
return goerliWeb3;
case NETWORK_IDS.POLYGON:
return polygonWeb3;
case NETWORK_IDS.XDAI:
return xdaiWeb3;
default:
throw new Error(i18n.__(translationErrorMessagesKeys.INVALID_NETWORK_ID));
}
export const getOriginHeader = () => {
const SERVICE_NAME = process.env.SERVICE_NAME;
return 'impact-graph-' + SERVICE_NAME || 'unnamed';
};

export function getProvider(networkId: number) {
const network = NETWORK_ID_MAP[networkId];
if (network === NETWORK_NAMES.XDAI) {
return new ethers.providers.JsonRpcProvider(
config.get('XDAI_NODE_HTTP_URL') as string,
);
return new ethers.providers.JsonRpcProvider({
url: config.get('XDAI_NODE_HTTP_URL') as string,
headers: {
Origin: getOriginHeader(),
},
});
}
// 'https://bsc-dataseed.binance.org/'
if (network === NETWORK_NAMES.BSC) {
return new ethers.providers.JsonRpcProvider(
config.get('BSC_NODE_HTTP_URL') as string,
{
url: config.get('BSC_NODE_HTTP_URL') as string,
headers: {
Origin: getOriginHeader(),
},
},
{ name: NETWORK_NAMES.BSC, chainId: NETWORK_IDS.BSC },
);
}
return new ethers.providers.InfuraProvider(network, INFURA_API_KEY);
const connectionInfo = ethers.providers.InfuraProvider.getUrl(
ethers.providers.getNetwork(networkId),
{ projectId: INFURA_API_KEY },
);
connectionInfo.headers = {
...connectionInfo.headers,
Origin: getOriginHeader(),
};
return new ethers.providers.JsonRpcProvider(connectionInfo);
}

export function getBlockExplorerApiUrl(networkId: number): string {
Expand Down
4 changes: 2 additions & 2 deletions src/resolvers/donationResolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import {
updateDonationQueryValidator,
validateWithJoiSchema,
} from '../utils/validators/graphqlQueryValidators';
import Web3 from 'web3';
import { logger } from '../utils/logger';
import { findUserById } from '../repositories/userRepository';
import {
Expand All @@ -57,6 +56,7 @@ import { findProjectById } from '../repositories/projectRepository';
import { AppDataSource } from '../orm';
import { getChainvineAdapter } from '../adapters/adaptersFactory';
import { CHAIN_ID } from '@giveth/monoswap/dist/src/sdk/sdkFactory';
import { ethers } from 'ethers';

@ObjectType()
class PaginateDonations {
Expand Down Expand Up @@ -440,7 +440,7 @@ export class DonationResolver {

// WalletAddresses are translanted to huge integers
// this breaks postgresql query integer limit
if (!Web3.utils.isAddress(searchTerm)) {
if (!ethers.utils.isAddress(searchTerm)) {
const amount = Number(searchTerm);

qb.orWhere('donation.amount = :number', {
Expand Down
16 changes: 8 additions & 8 deletions src/services/blockByDateService.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { getBlockByTime } from './blockByDateService';
import { assert } from 'chai';
import { getNetworkWeb3, NETWORK_IDS } from '../provider';
import { getProvider, NETWORK_IDS } from '../provider';
import { sleep } from '../utils/utils';

describe('block by date tests', () => {
Expand All @@ -19,8 +19,8 @@ describe('block by date tests', () => {
});

it('should return closest block to a random time', async () => {
const web3 = getNetworkWeb3(NETWORK_IDS.XDAI);
const firstBlock = await web3.eth.getBlock(1);
const provider = getProvider(NETWORK_IDS.XDAI);
const firstBlock = await provider.getBlock(1);
const now = Math.floor(Date.now() / 1000);
// A random time between 1970-01-01 and two minutes ago

Expand All @@ -30,25 +30,25 @@ describe('block by date tests', () => {
const blockNumber = await getBlockByTime(time);

const [previousBlock, nextBlock] = await Promise.all([
web3.eth.getBlock(blockNumber - 1),
web3.eth.getBlock(blockNumber + 1),
provider.getBlock(blockNumber - 1),
provider.getBlock(blockNumber + 1),
]);
assert.isBelow(time, +nextBlock.timestamp);
assert.isAbove(time, +previousBlock.timestamp);
});

it('should return correct balance after delay', async () => {
const web3 = getNetworkWeb3(NETWORK_IDS.XDAI);
const provider = getProvider(NETWORK_IDS.XDAI);
let [block, blockNumber] = await Promise.all([
web3.eth.getBlock('latest'),
provider.getBlock('latest'),
getBlockByTime(Date.now() / 1000),
]);

assert.isAtLeast(blockNumber, block.number - 1);

await sleep(20000); // about 3 blocks
[block, blockNumber] = await Promise.all([
web3.eth.getBlock('latest'),
provider.getBlock('latest'),
getBlockByTime(Date.now() / 1000),
]);
assert.isAtLeast(blockNumber, block.number - 1);
Expand Down
16 changes: 8 additions & 8 deletions src/services/blockByDateService.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { getNetworkWeb3, NETWORK_IDS } from '../provider';
import Web3 from 'web3';
import { getProvider, NETWORK_IDS } from '../provider';
import moment from 'moment';
import { logger } from '../utils/logger';
import { ethers } from 'ethers';

interface WrappedBlock {
number: number;
Expand All @@ -16,16 +16,16 @@ interface Block {

// Copied mostly from https://github.com/monosux/ethereum-block-by-date/blob/a71dd26f6a6ffe26b3c2202d6666d52e00a63435/src/ethereum-block-by-date.js
class BlockByDate {
web3: Web3;
provider: ethers.providers.Provider;
checkedBlocks: {};
savedBlocks: {};
requests: number;
latestBlock: WrappedBlock;
firstBlock: WrappedBlock;
blockTime: number | string;

constructor(web3) {
this.web3 = web3.eth !== undefined ? web3 : { eth: web3 };
constructor(provider) {
this.provider = provider;
this.checkedBlocks = {};
this.savedBlocks = {};
this.requests = 0;
Expand Down Expand Up @@ -136,11 +136,11 @@ class BlockByDate {
async getBlockWrapper(block) {
if (this.savedBlocks[block]) return this.savedBlocks[block];
logger.debug(
'NODE RPC request count - getBlockWrapper web3.eth.getBlock:',
'NODE RPC request count - getBlockWrapper provider.getBlock:',
block,
);
// tslint:disable-next-line:variable-name
const { number, timestamp } = await this.web3.eth.getBlock(block);
const { number, timestamp } = await this.provider.getBlock(block);
this.savedBlocks[number] = {
timestamp,
number,
Expand All @@ -153,7 +153,7 @@ class BlockByDate {
export const getBlockByTime = async (timeSecond: number): Promise<number> => {
// Create the object again because using the same object caused returns null after a while!
// It won't affect the performance, because each block will be seeked will be out of cached blocked
const blockByDate = new BlockByDate(getNetworkWeb3(NETWORK_IDS.XDAI));
const blockByDate = new BlockByDate(getProvider(NETWORK_IDS.XDAI));
const block = await blockByDate.getDate(timeSecond * 1000);
return block.block;
};
Loading

0 comments on commit 740bc39

Please sign in to comment.