diff --git a/packages-python/cactus_validator_socketio_iroha/README.md b/packages-python/cactus_validator_socketio_iroha/README.md new file mode 100644 index 0000000000..4d39933b7b --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/README.md @@ -0,0 +1,92 @@ +# Socket.io-typed Validator for Iroha + +## Features + +This validator codes provides the following features: +- execSyncFunction (* under construction) +- sendSignedTransaction (* under construction) +- monitoring blocks + +## How to test this validator + +### Requirements: + +- OS: Linux (Ubuntu or CentOS) +- node.js: v12 +- python: v3.8 +- Available port number: 5060 + +### How to execute test client (in the current status, only the monitor feature can be tested) + +1. Launch [iroha-testnet](https://github.com/hyperledger/cactus/tree/main/tools/docker/iroha-testnet) docker and execute its wallet script + ``` + $ cd cactus/tools/docker/iroha-testnet/ + $ docker-compose up -d + $ cd example/iroha-wallet + $ bash setup-iroha-wallet.sh + ``` + +1. Launch validator server on the first console + ``` + $ cd cactus/packages-python/cactus_validator_socketio_iroha/validator-python + $ pip3 install websocket eventlet flask requests flask-socketio==4.3.2 pyyaml pyjwt cryptography iroha schedule + $ python3 -m main + ``` + - If there is the following message on your first console, the validator is successfully launched. + + ``` + socket port: 5060 + Server initialized for eventlet. + ``` + +1. Execute test script on the second console + + ``` + $ cd cactus/packages-python/cactus_validator_socketio_iroha/testcli + $ npm install + $ node testsock.js + ``` + + - If there is the following message on your second console, the block monitoring request is successfully executed. + + ``` + connect + 81680a4dc06a4685b8219b22fd002023 + polling + call nop! + ##exec requestStartMonitor() + ``` + + - After this request is executed, the messages about monitoring blocks (`##get_block block num is : n`) will appear on your first console. + + ``` + 81680a4dc06a4685b8219b22fd002023: Sending packet OPEN data {'sid': '81680a4dc06a4685b8219b22fd002023', 'upgrades': ['websocket'], 'pingTimeout': 60000, 'pingInterval': 25000} + on connect (sessionid: 81680a4dc06a4685b8219b22fd002023) + ##called getValidatorInstance() + ##IrohaConnector.__init__ + 81680a4dc06a4685b8219b22fd002023: Sending packet MESSAGE data 0 + 81680a4dc06a4685b8219b22fd002023: Received request to upgrade to websocket + 81680a4dc06a4685b8219b22fd002023: Received packet MESSAGE data 2["test-event"] + received event "test-event" from 81680a4dc06a4685b8219b22fd002023 [/] + ##IrohaConnector.cb() + 81680a4dc06a4685b8219b22fd002023: Upgrade to websocket successful + 81680a4dc06a4685b8219b22fd002023: Received packet MESSAGE data 2["nop"] + received event "nop" from 81680a4dc06a4685b8219b22fd002023 [/] + received nop + ##IrohaConnector.nop() + 81680a4dc06a4685b8219b22fd002023: Received packet MESSAGE data 2["startMonitor"] + received event "startMonitor" from 81680a4dc06a4685b8219b22fd002023 [/] + on startMonitor + ##called monitoring_routine() + ##get_block block num is : 1 + ##get_block block num is : 2 + ##get_block block num is : 3 + ... + ##get_block block num is : 12 + ``` + + - After 180 seconds on the second console, run requestStopMonitor and the test script will stop running. + + ``` + ##exec requestStopMonitor() + ``` diff --git a/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-settings.yaml b/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-settings.yaml new file mode 100644 index 0000000000..ae36e343f0 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-settings.yaml @@ -0,0 +1,2 @@ +port: 8000 +logging_dir: "" \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-validator-registry.yaml b/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-validator-registry.yaml new file mode 100644 index 0000000000..9e87144846 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/etc/cactus/node-validator-registry.yaml @@ -0,0 +1,3 @@ +proto: "" +url: "" +publickey: "" \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-secrets.yaml b/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-secrets.yaml new file mode 100644 index 0000000000..6ce11b1ec5 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-secrets.yaml @@ -0,0 +1,2 @@ +sign_key: "" +auth_credential: "" \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-settings.yaml b/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-settings.yaml new file mode 100644 index 0000000000..069eea8cb5 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/etc/cactus/validator-001-settings.yaml @@ -0,0 +1 @@ +port: 5060 \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/testcli/3PfTJw8g.crt b/packages-python/cactus_validator_socketio_iroha/testcli/3PfTJw8g.crt new file mode 100644 index 0000000000..34773b65c3 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/testcli/3PfTJw8g.crt @@ -0,0 +1,10 @@ +-----BEGIN CERTIFICATE----- +MIIBdTCCARoCCQC/F+Mh551QzDAKBggqhkjOPQQDAjBCMQswCQYDVQQGEwJKUDEQ +MA4GA1UECAwHZXNqbXMxMjEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkg +THRkMB4XDTE4MDYyNzA3MjIzNVoXDTI4MDYyNDA3MjIzNVowQjELMAkGA1UEBhMC +SlAxEDAOBgNVBAgMB2Vzam1zMTIxITAfBgNVBAoMGEludGVybmV0IFdpZGdpdHMg +UHR5IEx0ZDBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABDPpSD2w0zrqJKraGD1b +5Jq2sDuacThSUqi7fvz8oyrWtuKDjZ15zIaSOtak6XRxFh9V9Gokdg5GNbW/pTZc +TuowCgYIKoZIzj0EAwIDSQAwRgIhAKH6ERsyd5bpEMIkY4clPqguwDWoTLk2VKq6 +ONEhUqotAiEA4yJxGmZpFdRScG2gDUIF2VDeX+XfHdJI2J41hyW9/zI= +-----END CERTIFICATE----- diff --git a/packages-python/cactus_validator_socketio_iroha/testcli/package.json b/packages-python/cactus_validator_socketio_iroha/testcli/package.json new file mode 100644 index 0000000000..3a7559f248 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/testcli/package.json @@ -0,0 +1,10 @@ +{ + "name": "testcli", + "version": "0.0.0", + "private": true, + "dependencies": { + "json-bigint": "^1.0.0", + "jsonwebtoken": "^8.5.1", + "socket.io-client": "^2.4.0" + } +} diff --git a/packages-python/cactus_validator_socketio_iroha/testcli/testsock.js b/packages-python/cactus_validator_socketio_iroha/testcli/testsock.js new file mode 100644 index 0000000000..3dda19aa90 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/testcli/testsock.js @@ -0,0 +1,102 @@ +const fs = require("fs"); +const jwt = require("jsonwebtoken"); +const JSONbig = require('json-bigint'); + +// NOTE: Run pip install socket.io-client. +const io = require('socket.io-client'); +const url = "http://localhost:5060"; +const socket = io(url, { + //transports: [ 'websocket', 'polling'] +}); + +const crtPath = "3PfTJw8g.crt"; +const paramAlgorithm = "ES256"; + +socket.on('connect', () => { + console.log('connect'); + console.log(socket.id); + const transport = socket.io.engine.transport.name; + console.log(transport); + //socket.emit('mymessage', 'hoge'); +}); + +socket.on('mymessage', () => { + console.log('received mymessage'); +}); + +socket.on("response", (result) => { + console.log(`#[recv]response, res: ${result}`); + responseFlag = true; + decodeFunc(result.resObj.data); +}); + +socket.on("eventReceived", (result) => { + console.log(`#[recv]eventReceived, res: ${result}`); + responseFlag = true; + console.log(`#[recv]eventReceived, res_status: ${result.status}`) + decodeFunc(result.blockData); +}); + +const verify = (signature) => new Promise(resolve => { + const publicKey = fs.readFileSync(crtPath); + + const option = { + algorithms: paramAlgorithm, + }; + + jwt.verify(signature, publicKey, option, (err, decoded) => { + return new Promise((resolve, reject) => { + if (err) { + // Authentication NG + console.log(`Authentication NG : error = ${err}`); + reject(err); + } else { + // Authentication OK + console.log(`Authentication OK`); + console.log(`decoded : ${JSON.stringify(decoded)}`); + + resolve(decoded); + } + }); + }); +}); + +const decodeFunc = async (signsignature) => { + try { + console.log("call verify()"); + console.log(`##signsignature: ${signsignature}`); + const decoded = await verify(signsignature); + console.log(`##decoded: ${decoded}`); + + } catch (err) { + console.log(`err: ${err}`); + } +}; + +const requestStartMonitor = () => { + console.log('##exec requestStartMonitor()'); + socket.emit('startMonitor'); + + setTimeout(requestStopMonitor,180000); +} + +const requestStopMonitor = () => { + console.log('##exec requestStopMonitor()'); + socket.emit('stopMonitor'); + + setTimeout(function(){ + // end communication + socket.disconnect(); + process.exit(0); + },5000); +} + +setTimeout(requestStartMonitor, 2000); + +socket.emit('test-event'); + +setTimeout(() => { + console.log('call nop!'); + socket.emit('nop'); +}, 1000); + diff --git a/packages-python/cactus_validator_socketio_iroha/testscript/Monitoring.py b/packages-python/cactus_validator_socketio_iroha/testscript/Monitoring.py new file mode 100644 index 0000000000..df01aee95e --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/testscript/Monitoring.py @@ -0,0 +1,86 @@ +from typing import Type +from iroha import Iroha, IrohaCrypto, IrohaGrpc +import schedule + +net = IrohaGrpc('localhost:50051') + +iroha = Iroha('admin@test') +admin_priv_key = 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70' #Private Key of user decided at previous line + +temp_blocks = [] +latestNumOfBlocks = 0 +isMonitoring = False + +def init(): + global temp_blocks + global latestNumOfBlocks + global isMonitoring + temp_blocks = [] + latestNumOfBlocks = 0 + isMonitoring = True + get_diff_blocks() + clear_temp_blocks() + +def get_block(blockNum): + # create Query + get_block_query = iroha.query( + 'GetBlock', + height = blockNum + ) + # sign Query + IrohaCrypto.sign_query(get_block_query, admin_priv_key) + # send Query + response = net.send_query(get_block_query) + return response + +def get_diff_blocks(): + print("called get_diff_blocks") + global temp_blocks + global latestNumOfBlocks + + print(f"latestNumOfBlocks before execute: {latestNumOfBlocks}") + + height = latestNumOfBlocks + is_latest = False + + # get blocks from latestNumOfBlocks + 1 + while(not is_latest): + height += 1 + response = get_block(height) + + if(response.error_response.error_code == 0): + temp_blocks.append(response) + elif(response.error_response.error_code == 3): + print(response.error_response.message) + latestNumOfBlocks = height - 1 + is_latest = True + + print(f"latestNumOfBlocks after execute: {latestNumOfBlocks}") + +def clear_temp_blocks(): + print("called clear_temp_blocks") + global temp_blocks + temp_blocks = [] + +def monitoring_routine(): + get_diff_blocks() + print("temp_blocks") + print(temp_blocks) + # send blocks to verifier + # TODO implement + #after sending, clear temp + clear_temp_blocks() + + +# start monitoring +# when starting monitoring, call get_diff_blocks and clear_temp_blocks once as for get latest number of blocks +init() + +schedule.every(1).minutes.do(monitoring_routine) + +while isMonitoring: + schedule.run_pending() + +print("finish") + + diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/.gitignore b/packages-python/cactus_validator_socketio_iroha/validator-python/.gitignore new file mode 100644 index 0000000000..d9d719b440 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/.gitignore @@ -0,0 +1,2 @@ +__pycache__ +*.log diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/3PfTJw8g.priv b/packages-python/cactus_validator_socketio_iroha/validator-python/3PfTJw8g.priv new file mode 100644 index 0000000000..6faf76a31e --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/3PfTJw8g.priv @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEICIlCfK3zMTFzUgdaj01LAHjJmHlbg6Xql9+i70iPz5EoAoGCCqGSM49 +AwEHoUQDQgAEM+lIPbDTOuokqtoYPVvkmrawO5pxOFJSqLt+/PyjKta24oONnXnM +hpI61qTpdHEWH1X0aiR2DkY1tb+lNlxO6g== +-----END EC PRIVATE KEY----- diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/main.py b/packages-python/cactus_validator_socketio_iroha/validator-python/main.py new file mode 100644 index 0000000000..fc7062fc94 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/main.py @@ -0,0 +1,5 @@ +from validator_socketio_module.SocketIoValidator import SocketIoValidator + +if __name__ == '__main__': + validator = SocketIoValidator() + validator.run() diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/AbstractConnector.py b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/AbstractConnector.py new file mode 100644 index 0000000000..ef77d5f646 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/AbstractConnector.py @@ -0,0 +1,46 @@ +from abc import ABCMeta, abstractmethod + +class AbstractConnector: + @abstractmethod + def __init__(self): + pass + + @abstractmethod + def getValidatorInformation(self, validatorURL): + """Get the validator information including version, name, ID, and other information""" + pass + + @abstractmethod + def sendSignedTransaction(self, signedTransaction): + """Request a verifier to execute a ledger operation""" + pass + + @abstractmethod + def getBalance(self, address): + """Get balance of an account for native token on a leder""" + pass + + @abstractmethod + def execSyncFunction(self, address, funcName, args): + """Execute a synchronous function held by a smart contract""" + pass + + @abstractmethod + def startMonitor(self, clientId, cb): + """Request a validator to start monitoring ledger""" + pass + + @abstractmethod + def stopMonitor(self, clientId): + """Request a validator to stop monitoring ledger""" + pass + + @abstractmethod + def cb(self, callbackData): + """Callback function to call when receiving data from Ledger""" + pass + + @abstractmethod + def nop(self): + """Nop function for testing""" + pass diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/IrohaConnector.py b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/IrohaConnector.py new file mode 100644 index 0000000000..9d05b6277a --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/IrohaConnector.py @@ -0,0 +1,101 @@ +from abc import ABCMeta, abstractmethod + +import asyncio + +from .AbstractConnector import AbstractConnector +from iroha import Iroha, IrohaCrypto, IrohaGrpc +import schedule + +class IrohaConnector(AbstractConnector): + def __init__(self, socketio, sessionid, iroha_dic, socketIoValidator): + self.moduleName = "IrohaConnector" + self.iroha_dic = iroha_dic + self.socketIoValidator = socketIoValidator + + self.net = IrohaGrpc('localhost:50051') + self.iroha = Iroha('admin@test') + self.admin_priv_key = 'f101537e319568c765b2cc89698325604991dca57b9716b58016b253506cab70' #Private Key of user decided at previous line + self.latestNumOfBlocks = 0 + self.isMonitoring = False + + print(f"##{self.moduleName}.__init__") + + def getValidatorInformation(self, validatorURL): + """Get the validator information including version, name, ID, and other information""" + print(f"##{self.moduleName}.getValidatorInformation()") + + def sendSignedTransaction(self, signedTransaction): + """Request a verifier to execute a ledger operation""" + print(f"##{self.moduleName}.sendSignedTransaction()") + + def getBalance(self, address): + """Get balance of an account for native token on a leder""" + print(f"##{self.moduleName}.getBalance()") + + def execSyncFunction(self, address, funcName, args): + """Execute a synchronous function held by a smart contract""" + print(f"##{self.moduleName}.execSyncFunction()") + + command = args['method']['command'] + print(f"##execSyncFunction : args['args']['args'] : {args['args']['args']}") + + def startMonitor(self): + """Request a validator to start monitoring ledger""" + + # initial execution for getting current number of blocks + self.monitoring_routine(True) + self.isMonitoring = True + print(f"##{self.moduleName}.startMonitor()") + schedule.every(1).minutes.do(self.monitoring_routine) + while self.isMonitoring: + schedule.run_pending() + + def stopMonitor(self): + """Request a validator to stop monitoring ledger""" + self.isMonitoring = False + print(f"##{self.moduleName}.stopMonitor()") + + def cb(self, callbackData): + """Callback function to call when receiving data from Ledger""" + print(f"##{self.moduleName}.cb()") + + def nop(self): + """Nop function for testing""" + print(f"##{self.moduleName}.nop()") + + def run_coroutine(self, coroutine, command, args, loop=None): + if loop is None: + loop = asyncio.get_event_loop() + result = loop.run_until_complete(coroutine(command, args)) + return result + + def get_block(self, blockNum): + print(f'##get_block block num is : {blockNum}') + + # create Query + get_block_query = self.iroha.query( + 'GetBlock', + height = blockNum + ) + # sign Query + IrohaCrypto.sign_query(get_block_query, self.admin_priv_key) + # send Query + response = self.net.send_query(get_block_query) + return response + + def monitoring_routine(self, isInit = False): + print(f'##called monitoring_routine()') + while(True): + blockData = self.get_block(self.latestNumOfBlocks + 1) + if(blockData.error_response.error_code == 0): + self.latestNumOfBlocks += 1 + if(not isInit): + event = self.extract_event(blockData) + self.socketIoValidator.publish_event(event) + elif(blockData.error_response.error_code == 3): + break + + def extract_event(self, blockData): + # TODO return event which is extracted from blockData + # improve temporary returning blockData + return blockData \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/Settings.py b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/Settings.py new file mode 100644 index 0000000000..fbd5122636 --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/Settings.py @@ -0,0 +1,61 @@ +import dataclasses +import yaml + +rootPath = "../" + +pathNodeSettings = rootPath + "etc/cactus/node-settings.yaml" +pathNodeValidatorRegistry = rootPath + "etc/cactus/node-validator-registry.yaml" +pathValidatorSettings = rootPath + "etc/cactus/validator-001-settings.yaml" +pathValidatorSecrets = rootPath + "etc/cactus/validator-001-secrets.yaml" + +#dataclass for validator--settings.yml +#data members should be equal to yml +@dataclasses.dataclass +class NodeSettings: + port: int + logging_dir: str + +#dataclass for validator--settings.yml +#data members should be equal to yml +@dataclasses.dataclass +class NodeValidatorRegistry: + proto: str + url: str + publickey: str + +#dataclass for validator--settings.yml +#data members should be equal to yml +@dataclasses.dataclass +class ValidatorSettings: + port: int + +#dataclass for validator--settings.yml +#data members should be equal to yml +@dataclasses.dataclass +class ValidatorSecrets: + sign_key: str + auth_credential: str + +@dataclasses.dataclass +class Settings: + nodeSettings: NodeSettings = None + nodeValidatorRegistry: NodeValidatorRegistry = None + validatorSettings: ValidatorSettings = None + validatorSecrets: ValidatorSecrets = None + + # this method is automatically implemented after generate object + def __post_init__(self): + + # todo fix these params + self.validatorSettings = ValidatorSettings(**(self.loadYaml(pathNodeSettings))) + self.validatorSettings = ValidatorSettings(**(self.loadYaml(pathNodeValidatorRegistry))) + self.validatorSettings = ValidatorSettings(**(self.loadYaml(pathValidatorSettings))) + self.validatorSettings = ValidatorSettings(**(self.loadYaml(pathValidatorSecrets))) + + + def loadYaml(self, yamlFilePath): + # load usersettings file + with open(pathValidatorSettings) as yamlFile: + yamlObj = yaml.safe_load(yamlFile) + + return yamlObj diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/SocketIoValidator.py b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/SocketIoValidator.py new file mode 100644 index 0000000000..df29ecaafa --- /dev/null +++ b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/SocketIoValidator.py @@ -0,0 +1,130 @@ +from flask import Flask, render_template, request +from flask_socketio import SocketIO +import jwt +import json + +from .Settings import Settings +from .IrohaConnector import IrohaConnector + +class SocketIoValidator: + def __init__(self): + self.moduleName = 'SocketIoValidator' + # self.the_cb = None + self.iroha_dic = {} + + # load settings + self.settings = Settings() + + self.app = Flask(__name__) + self.app.config['SECRET_KEY'] = 'secret!' + # socketio = SocketIO(app) + + print(f'socket port: {self.settings.validatorSettings.port}') + + self.socketio = SocketIO(self.app, host='0.0.0.0', port=self.settings.validatorSettings.port, logger=True, engineio_logger=True) + + self.privateKeyFile = '3PfTJw8g.priv' + self.algorithm = 'ES256' + + self.emitType = "eventReceived" + + @self.socketio.on('connect') + def handle_connect(): + print(f'on connect (sessionid: {request.sid})') + self.session_dict[request.sid] = self.getValidatorInstance() + + @self.socketio.on('disconnect') + def handle_disconnect(): + print('on disconnect') + del self.session_dict[request.sid] + + @self.socketio.on('startMonitor') + def handle_startMonitor(): + print('on startMonitor') + # clientId = None + # cb = None + # self.session_dict[request.sid].startMonitor(clientId, cb) + # def the_cb(resp): return self.cb_helper(request.sid, resp) + self.session_dict[request.sid].startMonitor() + + @self.socketio.on('stopMonitor') + def handle_stopMonitor(): + print('on stopMonitor') + self.session_dict[request.sid].stopMonitor() + + @self.socketio.on('nop') + def handle_nop(): + print('received nop') + self.session_dict[request.sid].nop() + + @self.socketio.on('test-event') + def handle_event(): + self.session_dict[request.sid].cb('data-from-blockchain') + + @self.socketio.on('request2') + def handle_execSyncFunction(requestData): + print('received request2') + print(f"##requestData: {requestData}") + + result = self.session_dict[request.sid].execSyncFunction(None, None, requestData) + + resp_obj = self.build_res_obj(200, requestData["reqID"], result) + #respJson = json.dumps(resp_obj) + self.socketio.emit("response", resp_obj) + + self.session_dict = {} + + # build response object of execSyncFunction + def build_res_obj(self, status_code, req_id, result): + + print(f"##build_res_obj result: {result}") + + signed_results = self.sign(result) + responseData = {} + res_obj = {} + res_obj["status"] = status_code + res_obj["data"] = signed_results + responseData["resObj"] = res_obj + if req_id is not None: + responseData["id"] = req_id + return responseData + + def run(self): + """Run Validator""" + # self.init_iroha(); + self.socketio.run(self.app, host='0.0.0.0', port=self.settings.validatorSettings.port) + + # def cb_helper(self, sessionid, answer): + # print(f'cb helper: {self.session_dict[request.sid]}') + # return self.session_dict[sessionid].cb(answer) + + def getValidatorInstance(self): + print(f'##called getValidatorInstance()') + return IrohaConnector(self.socketio, request.sid, self.iroha_dic, self) + + def sign(self, data): + """ sign data """ + print(f'##called sign()') + with open(self.privateKeyFile, 'br') as fh: + private_key = fh.read() + + print(f"raw data: {data}") + encoded_jwt = jwt.encode(data, private_key, algorithm="ES256") + print(f"encoded_jwt: {encoded_jwt}") + return encoded_jwt + + # build result of monitoring + def build_monitoring_result(self, blockData): + signedBlockData = self.sign({"blockData":json.dumps(blockData, default=str)}) + # Notify only if transaction exists + retObj = { + "status" : 200, + "blockData" : signedBlockData + } + print(f'##build_monitoring_result retObj : {retObj}') + return retObj + + # send result of monitoring using socket + def publish_event(self, event): + resp_obj = self.build_monitoring_result(event) + self.socketio.emit(self.emitType, resp_obj) \ No newline at end of file diff --git a/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/__init__.py b/packages-python/cactus_validator_socketio_iroha/validator-python/validator_socketio_module/__init__.py new file mode 100644 index 0000000000..e69de29bb2