This repository has been archived by the owner on Dec 1, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 13
/
start_validator.js
executable file
·107 lines (89 loc) · 4.16 KB
/
start_validator.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
#!/usr/bin/env node
const fs = require("mz/fs")
const fsEx = require("fs-extra")
const path = require("path")
const prettyjson = require("prettyjson")
const Web3 = require("web3")
const Validator = require("./src/validator")
const { throwIfNotContract } = require("./src/utils/checkArguments")
const defaultServers = require("./defaultServers.json")
const Channel = require("./src/joinPartChannel")
const {
CONFIG_JSON,
CONFIG_FILE,
CONFIG_URL,
ETHEREUM_SERVER,
ETHEREUM_NETWORK_ID,
ETHEREUM_PRIVATE_KEY,
WATCHED_ACCOUNTS,
STORE_DIR,
PLAYBACK_EVENTS_DIR,
QUIET,
} = process.env
const log = !QUIET ? console.log : () => {}
function error() {
console.error(...arguments)
process.exit(1)
}
const defaultConfigPath = __dirname + "/demo/public/data/state.json"
const storeDir = fs.existsSync(STORE_DIR) ? STORE_DIR : __dirname + "/temp"
const FileStore = require("./src/fileStore")
const fileStore = new FileStore(storeDir, log)
// TODO: get rid of this copy hack; past events sync should happen through the monoplasmaRouter and HTTP
const eventsDir = path.join(storeDir, "events")
const pastEventsDir = fs.existsSync(PLAYBACK_EVENTS_DIR) ? PLAYBACK_EVENTS_DIR : __dirname + "/demo/public/data/events"
log(`Channel playback hack: Copying past events ${pastEventsDir} -> ${eventsDir}`)
fsEx.copySync(pastEventsDir, eventsDir)
async function start() {
const config = CONFIG_JSON ? JSON.parse(CONFIG_JSON)
: CONFIG_FILE ? await loadStateFromFile(CONFIG_FILE)
: CONFIG_URL ? await loadStateFromUrl(CONFIG_URL)
: fs.existsSync(defaultConfigPath) ? await loadStateFromFile(defaultConfigPath)
: {}
log("Received config:")
log(prettyjson.render(config))
// TODO: validate config (operator state)
const ethereumNetworkId = ETHEREUM_NETWORK_ID || config.ethereumNetworkId
const ethereumServer = ETHEREUM_SERVER || defaultServers[ethereumNetworkId] || config.ethereumServer
if (!ethereumServer) { throw new Error("ethereumServer not found in config, please supply ETHEREUM_SERVER or ETHEREUM_NETWORK_ID you'd like to connect to as environment variable!") }
log(`Connecting to ${ethereumServer}...`)
const web3 = new Web3(ethereumServer)
let address = null
const accountList = WATCHED_ACCOUNTS ? WATCHED_ACCOUNTS.split(",") : []
if (accountList.length > 0) {
// TODO: guess private key if missing?
// with ganache, operator uses account 0: 0xa3d1f77acff0060f7213d7bf3c7fec78df847de1
let key = "0x5e98cce00cff5dea6b454889f359a4ec06b9fa6b88e9d69b86de8e1c81887da0"
if (ETHEREUM_PRIVATE_KEY) {
key = ETHEREUM_PRIVATE_KEY.startsWith("0x") ? ETHEREUM_PRIVATE_KEY : "0x" + ETHEREUM_PRIVATE_KEY
if (key.length !== 66) { throw new Error("Malformed private key, must be 64 hex digits long (optionally prefixed with '0x')") }
} else {
log("Environment variable ETHEREUM_PRIVATE_KEY not found, using key for address 0xa3d1f77acff0060f7213d7bf3c7fec78df847de1")
}
const account = web3.eth.accounts.wallet.add(key)
address = account.address
const balance = await web3.eth.getBalance(address)
if (+balance === 0) {
log(`Address ${address} has no ether, it is needed to send exit transaction for the WATCHED_ACCOUNTS!`)
//throw new Error("Ether is needed to send exit transaction for the WATCHED_ACCOUNTS!") }
}
}
await throwIfNotContract(web3, config.tokenAddress, "Config variable tokenAddress")
await throwIfNotContract(web3, config.contractAddress, "Config variable contractAddress")
// full playback
config.lastBlockNumber = 0
config.lastPublishedBlock = 0
log("Starting the joinPartChannel and Validator")
const channel = new Channel(config.channelPort)
const validator = new Validator(accountList, address, web3, channel, config, fileStore, log, error)
await validator.start()
}
async function loadStateFromFile(path) {
log(`Loading operator state from ${path}...`)
const raw = await fs.readFile(path)
return JSON.parse(raw)
}
async function loadStateFromUrl(url) {
throw new Error("not implemented, url: " + url)
}
start().catch(error)