Skip to content

Instantly share code, notes, and snippets.

@xtools-at
Created February 20, 2022 14:46
Show Gist options
  • Save xtools-at/dd543bbd05a0d75e43aebb1ca5492cd0 to your computer and use it in GitHub Desktop.
Save xtools-at/dd543bbd05a0d75e43aebb1ca5492cd0 to your computer and use it in GitHub Desktop.
RPC test (Moralis)
const Web3 = require('web3'); // [email protected]
const startBlock = 20784230;
const rpcMaxBlocksServer = 100 * 1000;
const rpcUrl = 'https://speedy-nodes-nyc.moralis.io/[YOUR_MORALIS_TOKEN]/polygon/mumbai';
const waitBatchRpcCalls = 250; // ms
// contract adresses and abis
const contracts = [
{
// game
address: '0xdb1Cc7F8756e319fc2CAFE39f56Df843dce8a8f1',
type: 'Battle',
abi: [{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "attacker",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "target",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "winner",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "xpEarned",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "ressLooted",
"type": "uint256"
}
],
"name": "Battle",
"type": "event"
}],
}, {
// market
address: '0x8524b159554b2Eab45152b7DcceB3BCEde21B012',
type: 'ListingStatus',
abi: [{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "listingId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint8",
"name": "status",
"type": "uint8"
},
{
"indexed": true,
"internalType": "address",
"name": "seller",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "price",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "buyer",
"type": "address"
}
],
"name": "ListingStatus",
"type": "event"
}],
}, {
// nft
address: '0x102d7d235795744d44f862cc8d92dCCC8F46112e',
type: 'Transfer',
abi: [{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": true,
"internalType": "uint256",
"name": "tokenId",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
}],
},
];
const wait = (ms) => {
return new Promise((resolve) => {
setTimeout(() => {
resolve();
}, ms);
});
};
// events
const getEventOptions = (filterObj, fromBlock, toBlock, noToBlock) => {
let toBlockObj = {};
if (!noToBlock) {
toBlockObj = {
toBlock: toBlock != null ? toBlock : 'latest',
};
}
return {
filter: filterObj || {},
fromBlock: fromBlock != null ? fromBlock : startBlock,
...toBlockObj,
};
};
const getEvents = (contract, type, filterObj, fromBlock, toBlock) => {
return contract.getPastEvents(type, getEventOptions(filterObj, fromBlock, toBlock));
};
// web3
const getWeb3 = () => {
return new Web3(new Web3.providers.HttpProvider(rpcUrl), {
keepalive: true,
headers: [{ name: 'Access-Control-Allow-Origin', value: '*' }],
withCredentials: false,
timeout: 30 * 1000, // s * ms, default: 10s
});
};
const web3Http = getWeb3();
const getContract = (contractConfig) => {
let contract;
try {
contract = new web3Http.eth.Contract(contractConfig.abi, contractConfig.address);
} catch (e) {
console.error(e);
}
return contract;
};
// main method
const getInitialEvents = async (contractConfig) => {
const eventType = contractConfig.type;
const currentBlock = await web3Http.eth.getBlockNumber();
console.log(`Starting to fetch ${eventType} events, current block:`, currentBlock);
const initialBlocks = currentBlock - startBlock;
if (initialBlocks > rpcMaxBlocksServer) {
// batch requests
let events = [];
const contract = getContract(contractConfig);
for (let i = 0; i < initialBlocks; i += rpcMaxBlocksServer) {
try {
const fromBlock = i + startBlock;
const toBlock = i + rpcMaxBlocksServer > initialBlocks ? 'latest' : fromBlock + rpcMaxBlocksServer - 1;
const batchEvents = await getEvents(
contract, eventType, null,
fromBlock, toBlock,
).catch((e) => {
console.error(`Error fetching initial ${eventType} events`, e);
return;
});
console.log('finished', i + rpcMaxBlocksServer, 'blocks, from/to block:', fromBlock, toBlock);
if (events == null) return null;
await wait(waitBatchRpcCalls);
events = events.concat(batchEvents);
} catch (e) {
console.error(`Error fetching initial ${eventType} events`, e);
return;
}
}
return events;
}
};
// start lookup
(async function() {
console.log(`start time: ${new Date().toUTCString()}`)
await getInitialEvents(contracts[0]);
console.log(`time after finishing first event class: ${new Date().toUTCString()}`)
await wait(200);
await getInitialEvents(contracts[1]);
console.log(`time after finishing 2nd event class: ${new Date().toUTCString()}`)
await wait(200);
await getInitialEvents(contracts[2]);
console.log(`time after finishing 3rd event class: ${new Date().toUTCString()}`)
console.log('Done');
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment