fix: initializing mining tree

This commit is contained in:
Danil Kovtonyuk 2021-10-09 02:50:21 +10:00
parent 8f5b673f3b
commit 043356f5fe
4 changed files with 91820 additions and 19 deletions

85902
cache/accounts_farmer_1.json vendored Normal file

File diff suppressed because it is too large Load Diff

5878
cache/accounts_farmer_5.json vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
{ {
"name": "relay", "name": "relay",
"version": "4.1.0", "version": "4.1.1",
"description": "Relayer for Tornado.cash privacy solution. https://tornado.cash", "description": "Relayer for Tornado.cash privacy solution. https://tornado.cash",
"scripts": { "scripts": {
"server": "node src/server.js", "server": "node src/server.js",

View File

@ -1,5 +1,5 @@
const MerkleTree = require('fixed-merkle-tree') const MerkleTree = require('fixed-merkle-tree')
const { redisUrl, wsRpcUrl, minerMerkleTreeHeight, torn } = require('./config') const { redisUrl, wsRpcUrl, minerMerkleTreeHeight, torn, netId } = require('./config')
const { poseidonHash2 } = require('./utils') const { poseidonHash2 } = require('./utils')
const { toBN } = require('web3-utils') const { toBN } = require('web3-utils')
const Redis = require('ioredis') const Redis = require('ioredis')
@ -21,19 +21,26 @@ let contract
// eslint-disable-next-line no-unused-vars // eslint-disable-next-line no-unused-vars
let tree, eventSubscription, blockSubscription let tree, eventSubscription, blockSubscription
// todo handle the situation when we have two rewards in one block async function fetchEvents(fromBlock, toBlock) {
async function fetchEvents(from = 0, to = 'latest') { if (fromBlock <= toBlock) {
try { try {
const events = await contract.getPastEvents('NewAccount', { return await contract.getPastEvents('NewAccount', {
fromBlock: from, fromBlock,
toBlock: to, toBlock,
}) })
return events } catch (error) {
.sort((a, b) => a.returnValues.index - b.returnValues.index) const midBlock = (fromBlock + toBlock) >> 1
.map(e => toBN(e.returnValues.commitment))
} catch (e) { if (midBlock - fromBlock < 2) {
console.error('error fetching events', e) throw new Error(`error fetching events: ${error.message}`)
}
const arr1 = await fetchEvents(fromBlock, midBlock)
const arr2 = await fetchEvents(midBlock + 1, toBlock)
return [...arr1, ...arr2]
}
} }
return []
} }
async function processNewEvent(err, event) { async function processNewEvent(err, event) {
@ -105,12 +112,26 @@ async function init() {
console.log('Initializing') console.log('Initializing')
const miner = await resolver.resolve(torn.miningV2.address) const miner = await resolver.resolve(torn.miningV2.address)
contract = new web3.eth.Contract(MinerABI, miner) contract = new web3.eth.Contract(MinerABI, miner)
const block = await web3.eth.getBlockNumber()
const events = await fetchEvents(0, block) const cachedEvents = require(`../cache/accounts_farmer_${netId}.json`)
tree = new MerkleTree(minerMerkleTreeHeight, events, { hashFunction: poseidonHash2 }) const cachedCommitments = cachedEvents.map(e => toBN(e.commitment))
const toBlock = await web3.eth.getBlockNumber()
const [{ blockNumber: fromBlock }] = cachedEvents.slice(-1)
const newEvents = await fetchEvents(fromBlock + 1, toBlock)
const newCommitments = newEvents
.sort((a, b) => a.returnValues.index - b.returnValues.index)
.map(e => toBN(e.returnValues.commitment))
.filter((item, index, arr) => !index || item != arr[index - 1])
const commitments = cachedCommitments.concat(newCommitments)
tree = new MerkleTree(minerMerkleTreeHeight, commitments, { hashFunction: poseidonHash2 })
await updateRedis() await updateRedis()
console.log(`Rebuilt tree with ${events.length} elements, root: ${tree.root()}`) console.log(`Rebuilt tree with ${commitments.length} elements, root: ${tree.root()}`)
eventSubscription = contract.events.NewAccount({ fromBlock: block + 1 }, processNewEvent)
eventSubscription = contract.events.NewAccount({ fromBlock: toBlock + 1 }, processNewEvent)
blockSubscription = web3.eth.subscribe('newBlockHeaders', processNewBlock) blockSubscription = web3.eth.subscribe('newBlockHeaders', processNewBlock)
} catch (e) { } catch (e) {
console.error('error on init treeWatcher', e.message) console.error('error on init treeWatcher', e.message)