Skip to content

Commit

Permalink
Enahnce the accounting functions
Browse files Browse the repository at this point in the history
  • Loading branch information
jensenbox committed Dec 5, 2017
1 parent ef0b61b commit f8891b0
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 37 deletions.
31 changes: 31 additions & 0 deletions agent/sn_agent/accounting/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,49 @@

from abc import ABC
from sn_agent.accounting.settings import AccountingSettings
from sn_agent.api import internal_perform_job
from sn_agent.job.job_descriptor import JobDescriptor
from sn_agent.network.sn import MarketJob


class PriceTooLowException(Exception):
pass

class IncorrectContractState(Exception):
pass

class Accounting(ABC):
def __init__(self, app):
self.app = app
self.settings = AccountingSettings()
self.network = app['network']

def job_is_contracted(self, job: JobDescriptor):
if not job is None:
return True
else:
return False

def incoming_offer(self, service_id, price):

if price < 0:
raise PriceTooLowException()

market_job = self.network.create_market_job(service_id, price)

return market_job.address

def perform_job(self, market_job_address, service_id, job_params):

market_job = self.network.get_market_job(market_job_address)

if market_job.state != MarketJob.PENDING:
raise IncorrectContractState()

result = internal_perform_job(self.app, service_id, job_params)

market_job.set_state = MarketJob.COMPLETED
return result

def setup_accounting(app):
app['accounting'] = Accounting(app)
27 changes: 14 additions & 13 deletions agent/sn_agent/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,7 @@
from aiohttp.web_response import Response
from jsonrpcserver.aio import methods

from sn_agent import ontology
from sn_agent.api.job import can_perform_service, perform_job
from sn_agent.job.job_descriptor import JobDescriptor
from sn_agent.ontology.service_descriptor import ServiceDescriptor
from sn_agent.api.job import internal_perform_job, internal_offer, internal_can_perform

logger = logging.getLogger(__name__)

Expand All @@ -17,22 +14,26 @@

@methods.add
async def can_perform(service_node_id=None, context=None):
# figure out what we are being asked to perform and answer
service = ServiceDescriptor(service_node_id)
app = context
return await can_perform_service(app, service)
logging.debug('Starting can perform for %s with params of %s', service_node_id)
result = await internal_can_perform(context, service_node_id)
logging.debug('Result of perform was %s', result)
return result


@methods.add
async def perform(service_node_id=None, job_params=None, context=None):
logging.debug('Starting perform for %s with params of %s', service_node_id, job_params)
service_descriptor = ServiceDescriptor(service_node_id)
result = await internal_perform_job(context, service_node_id, job_params)
logging.debug('Result of perform was %s', result)
return result

job = JobDescriptor(service_descriptor, job_params)
app = context

result = await perform_job(app, job)
logging.debug('Result of perform was %s', result)
@methods.add
async def offer(service_node_id=None, job_params=None, context=None):
price = job_params
logging.debug('Starting offer for %s with price of %s', service_node_id, price)
result = await internal_offer(context, service_node_id, price)
logging.debug('Result of offer was %s', result)
return result


Expand Down
20 changes: 19 additions & 1 deletion agent/sn_agent/api/job.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,25 @@
logger = logging.getLogger(__name__)


async def internal_can_perform(app, service_node_id):
# figure out what we are being asked to perform and answer
service = ServiceDescriptor(service_node_id)
return await can_perform_service(app, service)


async def internal_offer(app, service_node_id, price):
service_descriptor = ServiceDescriptor(service_node_id)
result = app['accounting'].incoming_offer(service_descriptor, price)
return result


async def internal_perform_job(app, service_node_id, job_params):
service_descriptor = ServiceDescriptor(service_node_id)
job = JobDescriptor(service_descriptor, job_params)
result = await perform_job(app, job)
return result


async def can_perform_service(app, service_descriptor: ServiceDescriptor):
logger.debug("get_can_perform: %s", service_descriptor)

Expand Down Expand Up @@ -40,4 +59,3 @@ async def perform_job(app, job_descriptor: JobDescriptor):
}]

return results

3 changes: 2 additions & 1 deletion agent/sn_agent/network/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

from urllib3.util import Url

from sn_agent import SettingsBase
from sn_agent import SettingsBase, Required

THIS_DIR = Path(__file__).parent

Expand All @@ -17,6 +17,7 @@ def __init__(self, **custom_settings):
self.GATEWAY = '0.0.0.0'

self.CLIENT_URL = 'http://testrpc:8545'
self.ACCOUNT_PASSWORD = Required(str)

self.CLASS = 'sn_agent.network.sn.SNNetwork'

Expand Down
37 changes: 30 additions & 7 deletions agent/sn_agent/network/sn.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,21 @@
logger = logging.getLogger(__name__)


class MarketJob(object):
UNKNOWN = None
PENDING = 'pending'
COMPLETED = 'completed'

def __init__(self):
self.state = self.UNKNOWN


class UnresolvedAgentException(Exception):
pass

class AccountNotUnlockedException(Exception):
pass


class FileResolver(ResolverABC):
def __init__(self, lookup_file):
Expand All @@ -31,10 +43,6 @@ def resolve(self, agent_id):
return agent_urls.get(agent_id)


class DHTResolver(ResolverABC):
def resolve(self, agent_id):
return None


class SNNetwork(NetworkABC):
def __init__(self, app):
Expand All @@ -47,7 +55,6 @@ def __init__(self, app):

self.resolvers = []
self.resolvers.append(FileResolver(self.settings.AGENT_URL_LOOKUP_FILE))
self.resolvers.append(DHTResolver())

async def startup(self):
logger.debug('Starting up the network')
Expand Down Expand Up @@ -135,7 +142,10 @@ def getAgentsById(self, id):
contract = self.get_agent_registry_contract()
return contract.call(self.payload).getAgent(id)

def createMarketJob(self, agents, amounts, payer, firstService, lastService):
def create_market_job(self, agents, amounts, payer, firstService, lastService):

self.ensure_unlocked()

contract = self.get_market_job_contract()
return contract.deploy(
transaction={
Expand All @@ -150,12 +160,19 @@ def createMarketJob(self, agents, amounts, payer, firstService, lastService):
)
)

def setJobCompleted(self):
def set_market_job_completed(self):
contract = self.get_market_job_contract()

self.ensure_unlocked()

return contract.call(self.payload).setJobCompleted()

def payAgent(self, agentAccounts):

contract = self.get_market_job_contract()

self.ensure_unlocked()

return contract.call({'from': agentAccounts[0]}).withdraw()

# Utility Functions
Expand Down Expand Up @@ -188,3 +205,9 @@ def get_contract(self, type_name):
address = self.getAddress(type_name)
contract = self.client_connection.eth.contract(abi=abi, address=address)
return contract

def ensure_unlocked(self):
unlock_state = self.client_connection.personal.unlockAccount(self.account, self.settings.ACCOUNT_PASSWORD, duration=30)

if not unlock_state:
raise AccountNotUnlockedException()
Empty file.
38 changes: 34 additions & 4 deletions agent/sn_agent/ui/templates/service-default.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,27 @@


{% block content %}

<link href="{{ static('jsoneditor/jsoneditor.css') }}" rel="stylesheet" type="text/css">
<script src="{{ static('jsoneditor/jsoneditor.js') }}"></script>

<style type="text/css">
#jsoneditor {
width: 100%;
height: 500px;
margin-bottom: 20px;
}
</style>

<div id="jsoneditor"></div>

<div id="app">
<button class="btn btn-success" @click="sendCanPerform">Can Perform</button>
<button class="btn btn-success" @click="sendOffer">Offer</button>
<button class="btn btn-success" @click="sendPerform">Perform</button>
</div>

<fieldset id="console-log-div"></fieldset>
<fieldset id="console-log-div"></fieldset>

<script src="{{ static('console-log-div.js') }}"></script>

Expand All @@ -21,15 +35,28 @@
var service_node_id = '{{ service_adapter.service.node_id }}';
var job_params = JSON.parse('{{ service_adapter.example_job_json() }}');
function successCB(response){
// create the editor
var container = document.getElementById("jsoneditor");
var options = {
mode: 'code'
};
var editor = new JSONEditor(container, options);
editor.set(job_params);
function successCB(response) {
var result = JSON.parse(response.bodyText)["result"];
var string_result = JSON.stringify(result, null, 2);
console.log(string_result);
}
function errorCB(response){
function errorCB(response) {
console.log(response);
}
Expand All @@ -39,12 +66,15 @@
this.sendJSONRPC("can_perform", service_node_id, false, successCB, errorCB);
},
sendOffer: function () {
this.sendJSONRPC("offer", service_node_id, false, successCB, errorCB);
this.sendJSONRPC("offer", service_node_id, 1.00, successCB, errorCB);
},
sendPerform: function () {
job_params = editor.get();
this.sendJSONRPC("perform", service_node_id, job_params, successCB, errorCB);
}
}
};
</script>

{% endblock %}
1 change: 1 addition & 0 deletions docker-compose.demo.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ services:
- SN_DS_TEST_OUTPUT_DIRECTORY=/data
- SN_NETWORK_CLIENT_URL=http://parity:8545
- SN_NETWORK_ACCOUNT=0x1934ab10860362eabcfaa111847bc75ecf43fcbd
- SN_NETWORK_ACCOUNT_PASSWORD=${SN_NETWORK_ACCOUNT_PASSWORD}
ports:
- "9250:9250"
volumes:
Expand Down
23 changes: 12 additions & 11 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ services:
- SN_AGENT_ID=b545478a-971a-48ec-bc56-4b9b7176799c
- SN_NETWORK_WEB_PORT=8000
- SN_SERVICE_ADAPTER_CONFIG_FILE=dev_config.yml
- SN_NETWORK_ACCOUNT_PASSWORD=${SN_NETWORK_ACCOUNT_PASSWORD}
ports:
- "8000:8000"
volumes:
Expand All @@ -17,17 +18,17 @@ services:
- testrpc
- relex

parity:
build: parity
ports:
- "8080:8080"
- "8180:8180"
- "8545:8545"
- "8546:8546"
- "30303:30303"
- "30303:30303/udp"
volumes:
- ./data/parity:/parity-data
# parity:
# build: parity
# ports:
# - "8080:8080"
# - "8180:8180"
# - "8545:8545"
# - "8546:8546"
# - "30303:30303"
# - "30303:30303/udp"
# volumes:
# - ./data/parity:/parity-data

testrpc:
build: testrpc
Expand Down
2 changes: 2 additions & 0 deletions tools.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ set -o errexit
set -o xtrace
set -o nounset

SN_NETWORK_ACCOUNT_PASSWORD=${SN_NETWORK_ACCOUNT_PASSWORD:=no_password_set}

case "$1" in

init)
Expand Down

0 comments on commit f8891b0

Please sign in to comment.