-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathetherscan_queries.test.js
131 lines (110 loc) · 3.67 KB
/
etherscan_queries.test.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const axios = require('axios');
const cron = require('node-cron');
require('dotenv').config();
const BASE_URL = process.env.ETHERSCAN_BASE_URL;
const API_KEY = process.env.ETHERSCAN_API_KEY;
const getLatestBlock = async () => {
try {
const response = await axios.get(BASE_URL, {
params: {
module: 'proxy',
action: 'eth_blockNumber',
apikey: API_KEY,
},
});
return parseInt(response.data.result, 16);
} catch (error) {
console.error(`Error fetching latest block: ${error.message}`);
return null;
}
};
const getTransactions = async (address, startBlock, endBlock) => {
const MAX_RESULTS = 10000;
let allTransactions = [];
async function fetchBatch(currentStartBlock) {
try {
const response = await axios.get(BASE_URL, {
params: {
module: 'account',
action: 'txlist',
address: address,
startblock: currentStartBlock,
endblock: endBlock,
sort: 'asc',
apikey: API_KEY,
},
});
if (response.data.status === '1') {
const transactions = response.data.result;
allTransactions = allTransactions.concat(transactions);
if (transactions.length === MAX_RESULTS) {
const lastBlockNumber = parseInt(transactions[transactions.length - 1].blockNumber);
console.log(`Fetched ${MAX_RESULTS} transactions, continuing from block ${lastBlockNumber + 1}`);
await new Promise(resolve => setTimeout(resolve, 200));
await fetchBatch(lastBlockNumber + 1);
}
} else {
console.error(`Error: ${response.data.message}`);
}
} catch (error) {
console.error(`Error fetching transactions: ${error.message}`);
}
}
await fetchBatch(startBlock);
return allTransactions;
};
const startScheduler = (initialBlock, testAddress) => {
let currentBlock = initialBlock;
const job = cron.schedule('*/12 * * * * *', async () => {
try {
const latestBlock = await getLatestBlock();
if (!latestBlock) {
console.error('Failed to fetch latest block');
return;
}
if (currentBlock > latestBlock) {
console.log('No new blocks to scrape');
return;
}
console.log(`Fetching transactions from blocks ${currentBlock} to ${latestBlock}...`);
const transactions = await getTransactions(testAddress, currentBlock, latestBlock);
if (transactions.length > 0) {
console.log(`Found ${transactions.length} transactions`);
}
currentBlock = latestBlock + 1;
return transactions;
} catch (error) {
console.error('Error in cron job:', error);
}
});
return {
stop: () => job.stop()
};
};
describe('Scheduler', () => {
it('should detect new transactions in subsequent blocks', async () => {
const TEST_ADDRESS = '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D';
const initialBlock = await getLatestBlock();
console.log(`Starting test at block ${initialBlock}`);
let newTransactionsFound = false;
const scheduler = startScheduler(initialBlock, TEST_ADDRESS);
await new Promise((resolve) => {
const timeout = setTimeout(() => {
scheduler.stop();
resolve();
}, 120000);
const interval = setInterval(() => {
if (newTransactionsFound) {
clearTimeout(timeout);
clearInterval(interval);
scheduler.stop();
resolve();
}
}, 1000);
});
const finalBlock = await getLatestBlock();
console.log(`Test ended at block ${finalBlock}`);
expect(finalBlock).toBeGreaterThan(initialBlock);
expect(newTransactionsFound).toBe(true);
}, 180000);
});