Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(validator): Indy validator and indy-testnet files #1099

Merged
merged 1 commit into from
Jul 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions packages-python/cactus_validator_socketio/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Starting Indy Valdiator

## Starting

### Build and run containers

go to cactus/tools/docker/indy-testnet and

```
$ cd cactus/tools/docker/indy-testnet
$ docker-compose -f ./under-construction-docker-compose.yaml up
Starting nginx ... done
Starting validator ... done
Starting indy_pool ... done
```

Type Ctrl + C to stop these containers.

### Verify that containers are actually up

Type following in the host environemnt:

```
 $ docker ps | grep -e indy_pool -e nginx -e valipy
```
Three containers `indy_pool`, `nginx` and `valipy` must be printed.

### Start Indy validator server

Run following commands (from host environment) to log into validator container:

```
$ sudo docker exec -it validator /bin/bash
```
and run the server using these commands:

```
$ cd /root/validator
$ pip install pyyaml
$ TEST_POOL_IP=172.16.0.2 python -m main
```

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
port: 8000
logging_dir: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
proto: ""
url: ""
publickey: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
sign_key: ""
auth_credential: ""
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
port: 8000
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"name": "testcli",
"version": "0.0.0",
"private": true,
"dependencies": {
"socket.io-client": "^4.1.2"
}
}
54 changes: 54 additions & 0 deletions packages-python/cactus_validator_socketio/testcli/testsock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
// NOTE: Run pip install socket.io-client.
const io = require('socket.io-client');
const url = "http://localhost:8000";
const socket = io(url, {
//transports: [ 'websocket', 'polling']
});

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', (respData) => {
console.log('received response from Validator');
// console.log(`##response : ${JSON.stringify(respData)}`);
const respObj = JSON.parse(respData);
console.log(`response(Obj) is ${JSON.stringify(respObj)}`);
});

// socket.emit('nop');
socket.emit('startMonitor');

socket.emit('test-event');

setTimeout(() => {
console.log('call request2!');

args_schema = "{\"reqId\":1624420883330729255,\"identifier\":\"8TAyhNonMhWGNRiRHRhs5C\",\"operation\":{\"type\":\"107\",\"dest\":\"HxuDdJmNSxboTCwLf8FN1j\",\"data\":{\"name\":\"Job-Certificate\",\"version\":\"0.2\"}},\"protocolVersion\":2}";
args_credential_definition = "{\"reqId\":1624437652192258330,\"identifier\":\"JbYRZdQeSkjxYKW61NReHN\",\"operation\":{\"type\":\"108\",\"ref\":14,\"signature_type\":\"CL\",\"origin\":\"DnZczRFF5iyiYgLMeFdHpk\",\"tag\":\"TAG1\"},\"protocolVersion\":2}";

// Call Validator
const requestData = {
contract: {"channelName": "mychannel", "contractName": "indysomething"},
method: {type: "evaluateTransaction", command: "indy_ledger_submit_request"},
args: args_credential_definition,
reqId: "reqID_test"
};

socket.emit('request2', requestData);

}, 2000);


setTimeout(() => {
console.log('call nop!');
socket.emit('nop');
}, 2000);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
__pycache__
*.log
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
from validator_socketio_module.SocketIoValidator import SocketIoValidator

if __name__ == '__main__':
validator = SocketIoValidator()
validator.init_indy()
validator.run()
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
from abc import ABCMeta, abstractmethod

import json
import time
from indy import ledger
import asyncio

from .AbstractConnector import AbstractConnector

class IndyConnector(AbstractConnector):
def __init__(self, socketio, sessionid, indy_dic):
self.moduleName = "IndyConnector"
self.indy_dic = indy_dic
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']
if command== 'indy_ledger_submit_request':
return self.load_schema_or_credential_definition(args['args'])

print(f"##{self.moduleName} unknown command : {command}")
return "unknown command."


def load_schema_or_credential_definition(self, args):
"""Execute a synchronous function held by a smart contract"""
print(f"##{self.moduleName}.load_schema_or_credential_definition()")

pool_handle = self.indy_dic['pool_handle']
responseStr = self.run_coroutine_ensure_previous_request_applied(pool_handle, args, lambda response: response['result']['data'] is not None)

response = json.loads(responseStr)

return response

def startMonitor(self, clientId, cb):
"""Request a validator to start monitoring ledger"""
print(f"##{self.moduleName}.startMonitor()")

def stopMonitor(self, clientId):
"""Request a validator to stop monitoring ledger"""
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()")

async def ensure_previous_request_applied(self, pool_handle, checker_request, checker):
for _ in range(3):
response = json.loads(await ledger.submit_request(pool_handle, checker_request))
try:
if checker(response):
return json.dumps(response)
except TypeError:
pass
time.sleep(5)

def run_coroutine_ensure_previous_request_applied(self, pool_handle, checker_request, checker, loop=None):
if loop is None:
loop = asyncio.get_event_loop()
results = loop.run_until_complete(self.ensure_previous_request_applied(pool_handle, checker_request, checker))
return results
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
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-<DLT id>-settings.yml
#data members should be equal to yml
@dataclasses.dataclass
class NodeSettings:
port: int
logging_dir: str

#dataclass for validator-<DLT id>-settings.yml
#data members should be equal to yml
@dataclasses.dataclass
class NodeValidatorRegistry:
proto: str
url: str
publickey: str

#dataclass for validator-<DLT id>-settings.yml
#data members should be equal to yml
@dataclasses.dataclass
class ValidatorSettings:
port: int

#dataclass for validator-<DLT id>-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):

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
Loading