2022-12-16 20:11:09 +00:00
|
|
|
# Nimbus
|
2024-02-28 17:31:45 +00:00
|
|
|
# Copyright (c) 2022-2024 Status Research & Development GmbH
|
2022-12-16 20:11:09 +00:00
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
|
|
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
|
|
|
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
|
|
|
|
|
|
|
# Tool to verify that certain Portal content is available on the network.
|
2024-07-11 15:42:45 +00:00
|
|
|
# Currently only supports checking `EpochRecord`s of the history network.
|
2022-12-16 20:11:09 +00:00
|
|
|
|
2023-01-31 12:38:08 +00:00
|
|
|
{.push raises: [].}
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
import
|
2024-02-28 17:31:45 +00:00
|
|
|
confutils,
|
|
|
|
chronicles,
|
|
|
|
chronicles/topics_registry,
|
|
|
|
stew/byteutils,
|
2022-12-16 20:11:09 +00:00
|
|
|
../network_metadata,
|
|
|
|
../network/history/[accumulator, history_content, history_network],
|
|
|
|
../rpc/portal_rpc_client
|
|
|
|
|
2024-02-28 17:31:45 +00:00
|
|
|
type ContentVerifierConf* = object
|
|
|
|
logLevel* {.
|
|
|
|
defaultValue: LogLevel.INFO,
|
|
|
|
defaultValueDesc: $LogLevel.INFO,
|
|
|
|
desc: "Sets the log level",
|
|
|
|
name: "log-level"
|
|
|
|
.}: LogLevel
|
2022-12-16 20:11:09 +00:00
|
|
|
|
2024-02-28 17:31:45 +00:00
|
|
|
rpcAddress* {.
|
|
|
|
desc: "Address of the JSON-RPC service",
|
|
|
|
defaultValue: "127.0.0.1",
|
|
|
|
name: "rpc-address"
|
|
|
|
.}: string
|
2022-12-16 20:11:09 +00:00
|
|
|
|
2024-02-28 17:31:45 +00:00
|
|
|
rpcPort* {.
|
|
|
|
defaultValue: 8545, desc: "Port of the JSON-RPC service", name: "rpc-port"
|
|
|
|
.}: uint16
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
proc checkAccumulators(client: RpcClient) {.async.} =
|
2024-03-19 15:45:32 +00:00
|
|
|
let accumulator = loadAccumulator()
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
for i, hash in accumulator.historicalEpochs:
|
|
|
|
let root = Digest(data: hash)
|
2024-07-11 15:42:45 +00:00
|
|
|
let contentKey = ContentKey.init(epochRecord, root)
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
try:
|
2024-03-26 21:27:31 +00:00
|
|
|
let contentInfo = await client.portal_historyRecursiveFindContent(
|
2024-02-28 17:31:45 +00:00
|
|
|
contentKey.encode.asSeq().toHex()
|
|
|
|
)
|
2022-12-16 20:11:09 +00:00
|
|
|
|
2024-07-11 15:42:45 +00:00
|
|
|
let res = decodeSsz(hexToSeqByte(contentInfo.content), EpochRecord)
|
2022-12-16 20:11:09 +00:00
|
|
|
if res.isErr():
|
2024-07-11 15:42:45 +00:00
|
|
|
echo "[Invalid] EpochRecord number " & $i & ": " & $root & " error: " & res.error
|
2022-12-16 20:11:09 +00:00
|
|
|
else:
|
2024-07-11 15:42:45 +00:00
|
|
|
let epochRecord = res.get()
|
|
|
|
let resultingRoot = hash_tree_root(epochRecord)
|
2022-12-16 20:11:09 +00:00
|
|
|
if resultingRoot == root:
|
2024-07-11 15:42:45 +00:00
|
|
|
echo "[Available] EpochRecord number " & $i & ": " & $root
|
2022-12-16 20:11:09 +00:00
|
|
|
else:
|
2024-07-11 15:42:45 +00:00
|
|
|
echo "[Invalid] EpochRecord number " & $i & ": " & $root &
|
2024-02-28 17:31:45 +00:00
|
|
|
" error: Invalid root"
|
2022-12-16 20:11:09 +00:00
|
|
|
except RpcPostError as e:
|
|
|
|
# RpcPostError when for example timing out on the request. Could retry
|
|
|
|
# in this case.
|
|
|
|
fatal "Error occured on JSON-RPC request", error = e.msg
|
|
|
|
quit 1
|
|
|
|
except ValueError as e:
|
|
|
|
# Either an error with the provided content key or the content was
|
|
|
|
# simply not available in the network
|
2024-07-11 15:42:45 +00:00
|
|
|
echo "[Not Available] EpochRecord number " & $i & ": " & $root & " error: " & e.msg
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
# Using the http connection re-use seems to slow down these sequentual
|
|
|
|
# requests considerably. Force a new connection setup by doing a close after
|
|
|
|
# each request.
|
|
|
|
await client.close()
|
|
|
|
|
|
|
|
proc run(config: ContentVerifierConf) {.async.} =
|
|
|
|
let client = newRpcHttpClient()
|
|
|
|
await client.connect(config.rpcAddress, Port(config.rpcPort), false)
|
|
|
|
|
|
|
|
await checkAccumulators(client)
|
|
|
|
|
|
|
|
when isMainModule:
|
|
|
|
{.pop.}
|
|
|
|
let config = ContentVerifierConf.load()
|
2023-01-31 12:38:08 +00:00
|
|
|
{.push raises: [].}
|
2022-12-16 20:11:09 +00:00
|
|
|
|
|
|
|
setLogLevel(config.logLevel)
|
|
|
|
|
|
|
|
waitFor run(config)
|