-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.js
188 lines (172 loc) · 6.29 KB
/
index.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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
const exec = require('child_process').exec
const Web3 = require("web3")
const web3 = new Web3()
const fs = require("fs")
const config = require('./config')
const util = require('./util.js')
const blockchainProxy1 = require('blockchain-proxy-client')({apiServerAddress: config.blockchainProxyAddress1})
const tokenProxy1 = require('token-proxy-client')({apiServerAddress: config.tokenProxyAddress1})
const blockchainProxy2 = require('blockchain-proxy-client')({apiServerAddress: config.blockchainProxyAddress2})
const tokenProxy2 = require('token-proxy-client')({apiServerAddress: config.tokenProxyAddress2})
const Clique = require("./build/contracts/Clique.json")
const clique = new web3.eth.Contract(Clique.abi)
let submittingSkippedBlocks = false
let processingSkippedMintEvents = false
const mintEventList = []
const newBlockList = []
function setLastSubmittedBlock(blockNumber) {
const obj = {
blockNumber
}
fs.writeFileSync(config.lastBlockStoreFile, JSON.stringify(obj))
}
function getLastSubmittedBlock() {
const data = JSON.parse(fs.readFileSync(config.lastBlockStoreFile))
return data
}
async function getSignedBlockHeader(blockNumber) {
return new Promise(function(resolve, reject) {
const rpcAddress = config.blockchainNodeRpcAddress
const pathToIonBinary = config.absolutePathToIonCli
const cmd = `${pathToIonBinary}/ion-cli ${rpcAddress} getBlockByNumber_Clique ${blockNumber} signed`
exec(cmd, async function(err, stdout, stderr) {
if(!!err) {
console.log('Error while trying to exec ion-cli:', err)
} else {
const signedHeader = stdout
resolve(signedHeader)
}
})
})
}
async function getUnsignedBlockHeader(blockNumber) {
return new Promise(function(resolve, reject) {
const rpcAddress = config.blockchainNodeRpcAddress
const pathToIonBinary = config.absolutePathToIonCli
const cmd = `${pathToIonBinary}/ion-cli ${rpcAddress} getBlockByNumber_Clique ${blockNumber} unsigned`
exec(cmd, async function(err, stdout, stderr) {
if(!!err) {
console.log('Error while trying to exec ion-cli:', err)
} else {
const unsignedHeader = stdout
resolve(unsignedHeader)
}
})
})
}
async function getProofData(txHash){
const rpcAddress = config.blockchainNodeRpcAddress
const pathToIonBinary = config.absolutePathToIonCli
const cmd = `${pathToIonBinary}/ion-cli ${rpcAddress} getProof ${txHash}`
await exec(cmd, async function(err, stdout, stderr) {
if(!!err) {
console.log('Error while trying to exec ion-cli:', err)
} else {
const proof = stdout.substring(stdout.indexOf('0x'))
console.log(proof)
}
})
}
async function submitSkippedBlocks(blockNumberStart, blockNumberEnd) {
const accounts = (await blockchainProxy2.accounts()).accounts
submittingSkippedBlocks = true
for (let i = blockNumberStart; i < blockNumberEnd; i++) {
const signedHeader = await getSignedBlockHeader(i)
const unsignedHeader = await getUnsignedBlockHeader(i)
const submitBlockTxData = clique.methods.SubmitBlock(config.chainId, unsignedHeader, signedHeader, config.blockStoreAddress).encodeABI()
const submitBlockTx = {
from: accounts[0],
to: config.validatorAddress,
value: '0x0',
gas: '0x'+Number(800000).toString(16),
gasPrice: '0x0',
data: submitBlockTxData
}
const submitBlockTxHash = await blockchainProxy2.sendTransaction(submitBlockTx)
console.log({submitBlockTxHash})
setLastSubmittedBlock(i)
const lastBlock = getLastSubmittedBlock()
console.log({lastBlock})
}
submittingSkippedBlocks = false
}
async function processNewBlocks(){
const newBlockEvent = newBlockList.shift()
if(!!newBlockEvent){
const blockNumber = JSON.parse(newBlockEvent.data).blockNumber
const prevBlockNumber = getLastSubmittedBlock().blockNumber
if (blockNumber > prevBlockNumber + 1) {
const blockNumberStart = prevBlockNumber + 1
const blockNumberEnd = blockNumber
submitSkippedBlocks(blockNumberStart, blockNumberEnd)
} else {
console.log(newBlockEvent)
console.log(await getSignedBlockHeader(blockNumber))
console.log(await getUnsignedBlockHeader(blockNumber))
}
}
}
async function processSkippedMintEvents() {
processingSkippedMintEvents = true
while (mintEventList.length > 0) {
const mintEvent = mintEventList.shift()
if(!!mintEvent){
const mintEventData = JSON.parse(mintEvent.data)
const txHash = mintEventData.contractEvent.transactionHash
// submit verifyAndTransfer tx here
await getProofData(txHash)
}
}
processingSkippedMintEvents = false
}
async function processMintEvents(){
if (mintEventList.length > 1) {
processSkippedMintEvents()
} else {
const mintEvent = mintEventList.shift()
if(!!mintEvent){
const mintEventData = JSON.parse(mintEvent.data)
const txHash = mintEventData.contractEvent.transactionHash
// submit verifyAndTransfer tx here
await getProofData(txHash)
}
}
}
async function processMintAndNewBlockEventsPeriodically() {
if (!submittingSkippedBlocks && !processingSkippedMintEvents) {
await processNewBlocks()
await processMintEvents()
}
setTimeout(processMintAndNewBlockEventsPeriodically, 500)
}
async function run(){
try{
const blockNumber = (await blockchainProxy1.getBlockNumber()).blockNumber
const tokenContractAddress = (await tokenProxy1.contractAddress()).contractAddress
const tokenContractABI = (await tokenProxy1.getTokenContractABI()).abi
const mintEventPrototype = (await tokenProxy1.getMintEventPrototype()).prototype
const filterOptions = JSON.stringify({
filter: {},
fromBlock: blockNumber,
topics: [mintEventPrototype]
})
blockchainProxy1.subscribeToContractEventsPubSub(tokenContractAddress
, tokenContractABI, filterOptions, function(event){
//wait for block to be added first
setTimeout(function() {
mintEventList.push(event)
}, 7000)
})
blockchainProxy1.subscribeToBlockNumbersPubSub(function(event) {
//wait for infura to make the new block available
setTimeout(function() {
newBlockList.push(event)
}, 5000)
})
processMintAndNewBlockEventsPeriodically()
} catch (err){
console.log('ERROR in index.js->run():', err)
process.exit(1)
}
}
run()