@tetherto/mdk-core 0.0.0 → 0.12.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +572 -0
- package/index.js +519 -0
- package/lib/address-policy.js +124 -0
- package/lib/local-discovery.js +321 -0
- package/lib/services/actions.service.js +68 -0
- package/lib/services/alerts.service.js +207 -0
- package/lib/services/comments.service.js +118 -0
- package/lib/services/log-history.service.js +307 -0
- package/lib/services/logs.service.js +249 -0
- package/lib/services/pool-utils/constants.js +20 -0
- package/lib/services/pool-utils/time.js +49 -0
- package/lib/services/pool.service.js +397 -0
- package/lib/services/provisioning.service.js +420 -0
- package/lib/services/settings.service.js +26 -0
- package/lib/services/snaps.service.js +181 -0
- package/lib/services/stats.service.js +205 -0
- package/lib/stats/README.md +80 -0
- package/lib/stats/index.js +57 -0
- package/lib/stats/ops/alerts_aggr.js +40 -0
- package/lib/stats/ops/alerts_group_cnt.js +43 -0
- package/lib/stats/ops/arr_concat.js +27 -0
- package/lib/stats/ops/array_obj_calc.js +41 -0
- package/lib/stats/ops/avg.js +42 -0
- package/lib/stats/ops/cnt.js +19 -0
- package/lib/stats/ops/group.js +38 -0
- package/lib/stats/ops/group_avg.js +53 -0
- package/lib/stats/ops/group_cnt.js +38 -0
- package/lib/stats/ops/group_max.js +40 -0
- package/lib/stats/ops/group_multiple_stats.js +40 -0
- package/lib/stats/ops/group_sum.js +40 -0
- package/lib/stats/ops/index.js +35 -0
- package/lib/stats/ops/nested_obj_concat.js +54 -0
- package/lib/stats/ops/obj_concat.js +33 -0
- package/lib/stats/ops/sum.js +27 -0
- package/lib/stats/utils.js +99 -0
- package/lib/templates/alerts.js +128 -0
- package/lib/templates/stats.js +476 -0
- package/lib/things/constants.js +65 -0
- package/lib/things/container.js +84 -0
- package/lib/things/miner.js +190 -0
- package/lib/things/powermeter.js +30 -0
- package/lib/things/sensor.js +18 -0
- package/lib/things/thing.js +93 -0
- package/lib/utils.js +603 -0
- package/lib/worker-infra.js +221 -0
- package/package.json +64 -1
- package/services.js +246 -0
- package/utils/compose-yaml.js +56 -0
- package/utils/constants.js +30 -0
- package/utils/index.js +29 -0
- package/utils/initialize.js +148 -0
- package/utils/service-bootstrap.js +271 -0
- package/worker.js +9 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('../utils')
|
|
4
|
+
|
|
5
|
+
function groupMax (op, cur, entry, ext) {
|
|
6
|
+
if (!cur) {
|
|
7
|
+
cur = { res: lUtils.createResMap() }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!entry) {
|
|
11
|
+
return cur
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (op.filter && !op.filter(entry)) {
|
|
15
|
+
return cur
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!op.group) {
|
|
19
|
+
return cur
|
|
20
|
+
}
|
|
21
|
+
const groupName = op.group(entry, ext)
|
|
22
|
+
|
|
23
|
+
if (!groupName || !lUtils.isSafeKey(groupName)) {
|
|
24
|
+
return cur
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!cur.res[groupName]) {
|
|
28
|
+
cur.res[groupName] = 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const val = lUtils.getVal(entry, op.src) || 0
|
|
32
|
+
|
|
33
|
+
cur.res[groupName] = cur.res[groupName] === undefined ? val : Math.max(cur.res[groupName], val)
|
|
34
|
+
|
|
35
|
+
return cur
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
calc: groupMax
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('../utils')
|
|
4
|
+
|
|
5
|
+
function groupMultipleStats (op, cur, entry, ext) {
|
|
6
|
+
if (!cur) {
|
|
7
|
+
cur = { res: lUtils.createResMap() }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!entry) {
|
|
11
|
+
return cur
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (!op.srcs || !Array.isArray(op.srcs)) {
|
|
15
|
+
return cur
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (op.filter && !op.filter(entry)) {
|
|
19
|
+
return cur
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!op.group) {
|
|
23
|
+
return cur
|
|
24
|
+
}
|
|
25
|
+
const groupName = op.group(entry, ext)
|
|
26
|
+
|
|
27
|
+
if (!groupName || !lUtils.isSafeKey(groupName)) {
|
|
28
|
+
return cur
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
cur.res[groupName] = op.srcs.reduce(
|
|
32
|
+
(prev, src) => ({ ...prev, [src.name]: lUtils.getVal(entry, src.src) }),
|
|
33
|
+
{}
|
|
34
|
+
)
|
|
35
|
+
return cur
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
calc: groupMultipleStats
|
|
40
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('../utils')
|
|
4
|
+
|
|
5
|
+
function groupSum (op, cur, entry, ext) {
|
|
6
|
+
if (!cur) {
|
|
7
|
+
cur = { res: lUtils.createResMap() }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!entry) {
|
|
11
|
+
return cur
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (op.filter && !op.filter(entry)) {
|
|
15
|
+
return cur
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
if (!op.group) {
|
|
19
|
+
return cur
|
|
20
|
+
}
|
|
21
|
+
const groupName = op.group(entry, ext)
|
|
22
|
+
|
|
23
|
+
if (!groupName || !lUtils.isSafeKey(groupName)) {
|
|
24
|
+
return cur
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
if (!cur.res[groupName]) {
|
|
28
|
+
cur.res[groupName] = 0
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const val = lUtils.getVal(entry, op.src)
|
|
32
|
+
|
|
33
|
+
cur.res[groupName] += val ? +val : 0
|
|
34
|
+
|
|
35
|
+
return cur
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
module.exports = {
|
|
39
|
+
calc: groupSum
|
|
40
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Static registry of stats ops. Op names come from stats specs (`op.op`,
|
|
4
|
+
// `objOps[].op`, `nestedOps[].op`), so they are never turned into a require
|
|
5
|
+
// path: an unknown name is refused instead of resolved on disk. Entries are
|
|
6
|
+
// lazy because array_obj_calc and nested_obj_concat look ops up themselves.
|
|
7
|
+
const OPS = {
|
|
8
|
+
alerts_aggr: () => require('./alerts_aggr'),
|
|
9
|
+
alerts_group_cnt: () => require('./alerts_group_cnt'),
|
|
10
|
+
arr_concat: () => require('./arr_concat'),
|
|
11
|
+
array_obj_calc: () => require('./array_obj_calc'),
|
|
12
|
+
avg: () => require('./avg'),
|
|
13
|
+
cnt: () => require('./cnt'),
|
|
14
|
+
group: () => require('./group'),
|
|
15
|
+
group_avg: () => require('./group_avg'),
|
|
16
|
+
group_cnt: () => require('./group_cnt'),
|
|
17
|
+
group_max: () => require('./group_max'),
|
|
18
|
+
group_multiple_stats: () => require('./group_multiple_stats'),
|
|
19
|
+
group_sum: () => require('./group_sum'),
|
|
20
|
+
nested_obj_concat: () => require('./nested_obj_concat'),
|
|
21
|
+
obj_concat: () => require('./obj_concat'),
|
|
22
|
+
sum: () => require('./sum')
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function getOp (name) {
|
|
26
|
+
if (typeof name !== 'string' || !Object.hasOwn(OPS, name)) {
|
|
27
|
+
throw new Error(`ERR_STATS_OP_UNKNOWN: ${String(name).slice(0, 64)}`)
|
|
28
|
+
}
|
|
29
|
+
return OPS[name]()
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
module.exports = {
|
|
33
|
+
getOp,
|
|
34
|
+
OP_NAMES: Object.freeze(Object.keys(OPS))
|
|
35
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('../utils')
|
|
4
|
+
const { getOp } = require('./index')
|
|
5
|
+
|
|
6
|
+
function nestedObjConcat (op, cur, entry, ext) {
|
|
7
|
+
if (!cur) {
|
|
8
|
+
cur = { res: lUtils.createResMap() }
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
if (!entry) {
|
|
12
|
+
return cur
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if (op.filter && !op.filter(entry)) {
|
|
16
|
+
return cur
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const val = lUtils.getVal(entry, op.src)
|
|
20
|
+
for (const keys in val) {
|
|
21
|
+
if (!lUtils.isSafeKey(keys)) continue
|
|
22
|
+
if (!cur.res[keys]) {
|
|
23
|
+
cur.res[keys] = val[keys]
|
|
24
|
+
} else {
|
|
25
|
+
const currObj = cur.res[keys]
|
|
26
|
+
const newObj = val[keys]
|
|
27
|
+
if (typeof newObj === 'object' && op.nestedOps) {
|
|
28
|
+
concatNestedObj(currObj, newObj, op.nestedOps)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return cur
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const concatNestedObj = (currObj, newObj, ops) => {
|
|
37
|
+
if (!currObj || typeof currObj !== 'object') return
|
|
38
|
+
for (const key in newObj) {
|
|
39
|
+
if (!lUtils.isSafeKey(key)) continue
|
|
40
|
+
const keyOp = ops.find(v => v.src === key)
|
|
41
|
+
if (keyOp) {
|
|
42
|
+
const calcFn = getOp(keyOp.op)
|
|
43
|
+
const calcRes = calcFn.calc(keyOp, currObj[key] && { res: currObj[key] }, newObj)
|
|
44
|
+
currObj[key] = calcRes.res
|
|
45
|
+
}
|
|
46
|
+
if (typeof newObj[key] === 'object' && !Array.isArray(newObj[key])) {
|
|
47
|
+
concatNestedObj(currObj[key], newObj[key], ops)
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
calc: nestedObjConcat
|
|
54
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('../utils')
|
|
4
|
+
|
|
5
|
+
function objConcat (op, cur, entry, ext) {
|
|
6
|
+
if (!cur) {
|
|
7
|
+
cur = { res: lUtils.createResMap() }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!entry) {
|
|
11
|
+
return cur
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (op.filter && !op.filter(entry)) {
|
|
15
|
+
return cur
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const val = lUtils.getVal(entry, op.src)
|
|
19
|
+
for (const keys in val) {
|
|
20
|
+
if (!lUtils.isSafeKey(keys)) continue
|
|
21
|
+
if (!cur.res[keys]) {
|
|
22
|
+
cur.res[keys] = val[keys]
|
|
23
|
+
} else {
|
|
24
|
+
cur.res[keys] += val[keys]
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return cur
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
module.exports = {
|
|
32
|
+
calc: objConcat
|
|
33
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const lUtils = require('./../utils')
|
|
4
|
+
|
|
5
|
+
function sum (op, cur, entry, ext) {
|
|
6
|
+
if (!cur) {
|
|
7
|
+
cur = { res: 0 }
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
if (!entry) {
|
|
11
|
+
return cur
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
if (op.filter && !op.filter(entry, ext)) {
|
|
15
|
+
return cur
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const val = lUtils.getVal(entry, op.src)
|
|
19
|
+
|
|
20
|
+
cur.res += val ? +val : 0
|
|
21
|
+
|
|
22
|
+
return cur
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
module.exports = {
|
|
26
|
+
calc: sum
|
|
27
|
+
}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
// Keypaths are a small, fixed grammar — `a.b.c`, `a[0].b`, `a['k']` — walked
|
|
4
|
+
// segment by segment. They used to be compiled with `new Function`, which made
|
|
5
|
+
// any caller-influenced keypath arbitrary code; the walker below cannot do more
|
|
6
|
+
// than read properties, and refuses the prototype-reaching names outright.
|
|
7
|
+
const FORBIDDEN_SEGMENTS = new Set(['__proto__', 'constructor', 'prototype'])
|
|
8
|
+
const SEGMENT_RE = /^(?:\.?([A-Za-z_$][\w$]*)|\[(\d+)\]|\[(?:'([^'\\]*)'|"([^"\\]*)")\])/
|
|
9
|
+
const MAX_KEYPATH_LENGTH = 512
|
|
10
|
+
const MAX_CACHED_KEYPATHS = 1024
|
|
11
|
+
|
|
12
|
+
const _parsed = new Map()
|
|
13
|
+
|
|
14
|
+
function parseKeypath (keypath) {
|
|
15
|
+
const cached = _parsed.get(keypath)
|
|
16
|
+
if (cached) return cached
|
|
17
|
+
|
|
18
|
+
if (keypath.length > MAX_KEYPATH_LENGTH) throw new Error('ERR_STATS_KEYPATH_INVALID: keypath too long')
|
|
19
|
+
|
|
20
|
+
const segments = []
|
|
21
|
+
let rest = keypath
|
|
22
|
+
while (rest.length) {
|
|
23
|
+
const m = SEGMENT_RE.exec(rest)
|
|
24
|
+
// A leading `.` is only valid between segments, never first.
|
|
25
|
+
if (!m || (segments.length === 0 && rest[0] === '.')) {
|
|
26
|
+
throw new Error(`ERR_STATS_KEYPATH_INVALID: ${keypath}`)
|
|
27
|
+
}
|
|
28
|
+
const seg = m[1] ?? m[2] ?? m[3] ?? m[4]
|
|
29
|
+
if (FORBIDDEN_SEGMENTS.has(seg)) {
|
|
30
|
+
throw new Error(`ERR_STATS_KEYPATH_FORBIDDEN: ${keypath}`)
|
|
31
|
+
}
|
|
32
|
+
segments.push(seg)
|
|
33
|
+
rest = rest.slice(m[0].length)
|
|
34
|
+
}
|
|
35
|
+
if (!segments.length) throw new Error(`ERR_STATS_KEYPATH_INVALID: ${keypath}`)
|
|
36
|
+
|
|
37
|
+
if (_parsed.size >= MAX_CACHED_KEYPATHS) _parsed.clear()
|
|
38
|
+
_parsed.set(keypath, segments)
|
|
39
|
+
return segments
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Same semantics as the old compiled `root.<keypath>` inside try/catch: any
|
|
43
|
+
// missing (null/undefined) link yields undefined instead of throwing.
|
|
44
|
+
function pathResolve (keypath) {
|
|
45
|
+
const segments = parseKeypath(keypath)
|
|
46
|
+
return (root) => {
|
|
47
|
+
let cur = root
|
|
48
|
+
for (const seg of segments) {
|
|
49
|
+
if (cur === null || cur === undefined) return undefined
|
|
50
|
+
cur = cur[seg]
|
|
51
|
+
}
|
|
52
|
+
return cur
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function getVal (entry, src) {
|
|
57
|
+
if (!src) {
|
|
58
|
+
return null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (typeof src === 'function') {
|
|
62
|
+
return src(entry)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (typeof src === 'string') {
|
|
66
|
+
return pathResolve(src)(entry)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return null
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Result maps in the stats ops are keyed by data (device `info.container`,
|
|
73
|
+
// alert severities, snapshot object keys). They are created without a
|
|
74
|
+
// prototype and these names are skipped, so a hostile key can neither reach
|
|
75
|
+
// nor pollute Object.prototype.
|
|
76
|
+
function isSafeKey (key) {
|
|
77
|
+
return typeof key !== 'symbol' && !FORBIDDEN_SEGMENTS.has(String(key))
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function createResMap () {
|
|
81
|
+
return Object.create(null)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const groupBy = (field) => {
|
|
85
|
+
return (entry, ext) => {
|
|
86
|
+
if (!ext) {
|
|
87
|
+
return null
|
|
88
|
+
}
|
|
89
|
+
return getVal(ext, field)
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
module.exports = {
|
|
94
|
+
getVal,
|
|
95
|
+
groupBy,
|
|
96
|
+
parseKeypath,
|
|
97
|
+
isSafeKey,
|
|
98
|
+
createResMap
|
|
99
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const { isValidSnap, isOffline } = require('../utils')
|
|
4
|
+
|
|
5
|
+
// Base alert spec data per device family. Workers compose their own
|
|
6
|
+
// { specs } template object from these — the exported objects are never
|
|
7
|
+
// mutated: one process can host several worker families, and a mutated module
|
|
8
|
+
// singleton would leak one family's specs into all of them.
|
|
9
|
+
|
|
10
|
+
function isValidPoolConfigSnap (ctx, snap) {
|
|
11
|
+
return (
|
|
12
|
+
isValidSnap(snap) &&
|
|
13
|
+
!isOffline(snap) &&
|
|
14
|
+
ctx.thingConf.pools &&
|
|
15
|
+
ctx.thingConf.pools.length > 0 &&
|
|
16
|
+
snap.config.pool_config &&
|
|
17
|
+
snap.config.pool_config.length > 0
|
|
18
|
+
)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function isIpPoolUsername (ip, minerPools, confPools) {
|
|
22
|
+
for (let i = 0; i < confPools.length; i++) {
|
|
23
|
+
const formattedIP = ip.replace(/\./g, 'x')
|
|
24
|
+
const username = minerPools[i].username
|
|
25
|
+
|
|
26
|
+
if (!username.includes(formattedIP)) {
|
|
27
|
+
return false
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return true
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function isCorrectPoolUsername (id, minerPools, confPools) {
|
|
34
|
+
for (let i = 0; i < confPools.length; i++) {
|
|
35
|
+
const username = minerPools[i].username
|
|
36
|
+
if (!username.includes(id)) {
|
|
37
|
+
return false
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return true
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function isConfigWorkerNameInPoolUsername (minerPools, confPools) {
|
|
44
|
+
for (let i = 0; i < confPools.length; i++) {
|
|
45
|
+
const workerName = confPools[i].worker_name
|
|
46
|
+
const username = minerPools[i].username
|
|
47
|
+
|
|
48
|
+
if (!username.includes(workerName)) {
|
|
49
|
+
return false
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return true
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
function areMinerPoolsUrlsCorrectlySetup (minerPools, confPools) {
|
|
56
|
+
return confPools.every((pool, i) => minerPools[i]?.url === pool.url)
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const DEFAULT = {}
|
|
60
|
+
|
|
61
|
+
const MINER_DEFAULT = {
|
|
62
|
+
...DEFAULT,
|
|
63
|
+
wrong_miner_pool: {
|
|
64
|
+
valid: (ctx, snap) => {
|
|
65
|
+
return isValidPoolConfigSnap(ctx, snap)
|
|
66
|
+
},
|
|
67
|
+
probe: (ctx, snap) => {
|
|
68
|
+
const configPools = ctx.thingConf.pools
|
|
69
|
+
const minerPools = snap.config.pool_config
|
|
70
|
+
return !areMinerPoolsUrlsCorrectlySetup(minerPools, configPools)
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
wrong_miner_subaccount: {
|
|
74
|
+
valid: (ctx, snap) => {
|
|
75
|
+
return isValidPoolConfigSnap(ctx, snap)
|
|
76
|
+
},
|
|
77
|
+
probe: (ctx, snap) => {
|
|
78
|
+
const configPools = ctx.thingConf.pools
|
|
79
|
+
const minerPools = snap.config.pool_config
|
|
80
|
+
if (configPools.length > 0 && minerPools.length > 0) {
|
|
81
|
+
return !isConfigWorkerNameInPoolUsername(minerPools, configPools)
|
|
82
|
+
}
|
|
83
|
+
return false
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
wrong_worker_name: {
|
|
87
|
+
valid: (ctx, snap) => {
|
|
88
|
+
return isValidPoolConfigSnap(ctx, snap)
|
|
89
|
+
},
|
|
90
|
+
probe: (ctx, snap) => {
|
|
91
|
+
const configPools = ctx.thingConf.pools
|
|
92
|
+
const minerPools = snap.config.pool_config
|
|
93
|
+
const id = ctx.id
|
|
94
|
+
const ip = snap.config.network_config.ip_address
|
|
95
|
+
if (configPools.length > 0 && minerPools.length > 0) {
|
|
96
|
+
return (
|
|
97
|
+
!isCorrectPoolUsername(id, minerPools, configPools) &&
|
|
98
|
+
!isIpPoolUsername(ip, minerPools, configPools)
|
|
99
|
+
)
|
|
100
|
+
}
|
|
101
|
+
return false
|
|
102
|
+
}
|
|
103
|
+
},
|
|
104
|
+
ip_worker_name: {
|
|
105
|
+
valid: (ctx, snap) => {
|
|
106
|
+
return isValidPoolConfigSnap(ctx, snap)
|
|
107
|
+
},
|
|
108
|
+
probe: (ctx, snap) => {
|
|
109
|
+
const configPools = ctx.thingConf.pools
|
|
110
|
+
const minerPools = snap.config.pool_config
|
|
111
|
+
const ip = snap.config.network_config.ip_address
|
|
112
|
+
|
|
113
|
+
if (configPools.length > 0 && minerPools.length > 0) {
|
|
114
|
+
return isIpPoolUsername(ip, minerPools, configPools)
|
|
115
|
+
}
|
|
116
|
+
return false
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
specs: {
|
|
123
|
+
default: DEFAULT,
|
|
124
|
+
miner_default: MINER_DEFAULT,
|
|
125
|
+
container_default: DEFAULT,
|
|
126
|
+
powermeter_default: {}
|
|
127
|
+
}
|
|
128
|
+
}
|