diff --git a/participant.py b/participant.py index 68fb1e6097badbd246b73c997dcd349c3700a4b1..e300206230d260843aeb8e7ddfc96ce1379adbd4 100644 --- a/participant.py +++ b/participant.py @@ -120,7 +120,7 @@ class Participant: now = datetime.now() next_min = (now + timedelta(minutes=1)).replace(second=0, microsecond=0) run_time = next_min - timedelta(seconds=5) - self.scheduler.add_job(job_function, 'interval', minutes=1, next_run_time=run_time) + self.scheduler.add_job(self.enact_Trades, 'interval', minutes=1, next_run_time=run_time) logger.info("~~~>Finished setup on " + self.publicIP.__str__()) @@ -348,7 +348,7 @@ class Participant: t.sig_chain[1].append((public_key, signature)) return jsonpickle.encode(t) logger.info("===> no suitable trade found") - raise HTTPException(status_code=404, detail="Trade not found") + raise HTTPException(status_code=406, detail="Trade not found") async def announceTrade(self, body=Body()): # here a Trade will be announced from another participant which @@ -509,7 +509,8 @@ class Participant: # create a trade, include offer and request, use power from request since we ensured that # the offer is big enough, use price from offer as this is the price that will be paid # and again, only trades for the next minute are possible at this point - t = Trade(o, self.ExchangeQueue[0], self.ExchangeQueue[0].power, o.pricePerWatt, r, + power = min(abs(o.power), abs(self.ExchangeQueue[0].power)) + t = Trade(o, self.ExchangeQueue[0], power, o.pricePerWatt, r, next_minute(), time.time_ns()) # now announce the route to all connections involved signedt = await self.announceRoute(t) @@ -554,22 +555,40 @@ class Participant: return "Error: Signature not valid" # route seems to be fine, now we can sign + # signing for offer with redirect_stdout(None): sig = self.dil.sign_with_input(self.__secretKey, signable_trade1.__repr__().encode()) - response = await client.post( + response_offer = await client.post( "http://" + signable_trade1.offer.publicIP.__str__() + ":8000/signTrade", json={"trade": jsonpickle.encode(signable_trade1), "public_key": jsonpickle.encode(self.publicKey), "signature": jsonpickle.encode(sig)}) - if response.status_code == 200: + if response_offer.status_code == 200: logger.info( "===> received confirmation from " + signable_trade1.offer.publicIP.__str__()) - signed_trade1 = jsonpickle.decode(response.json()) + signed_trade1 = jsonpickle.decode(response_offer.json()) confirmedt.confirmed_trades.append(signed_trade1) - if response.status_code == 404: + if response_offer.status_code == 406: logger.info( "===> no trade returned from " + signable_trade1.offer.publicIP.__str__()) + # signing for request + with redirect_stdout(None): + sig = self.dil.sign_with_input(self.__secretKey, + signable_trade1.__repr__().encode()) + response_req = await client.post( + "http://" + signable_trade1.request.publicIP.__str__() + ":8000/signTrade", + json={"trade": jsonpickle.encode(signable_trade1), + "public_key": jsonpickle.encode(self.publicKey), + "signature": jsonpickle.encode(sig)}) + if response_req.status_code == 200: + logger.info( + "===> received confirmation from " + signable_trade1.request.publicIP.__str__()) + signed_trade1 = jsonpickle.decode(response_req.json()) + confirmedt.confirmed_trades.append(signed_trade1) + if response_req.status_code == 406: + logger.info( + "===> no trade returned from " + signable_trade1.request.publicIP.__str__()) signable_trade2: Trade = await self.findConfirmableTrade() # verify the route of the trade @@ -600,12 +619,13 @@ class Participant: json={"trade": jsonpickle.encode(signable_trade2), "public_key": jsonpickle.encode(self.publicKey), "signature": jsonpickle.encode(sig)}) + # here the request should also be contacted to receive the signature if response.status_code == 200: logger.info( "===> received confirmation from " + signable_trade2.offer.publicIP.__str__()) signed_trade1 = jsonpickle.decode(response.json()) confirmedt.confirmed_trades.append(signed_trade1) - if response.status_code == 404: + if response.status_code == 406: logger.info( "===> no trade returned from " + signable_trade2.offer.publicIP.__str__()) # trying to get confirmation for a trade must happen more often than just after creating it @@ -649,15 +669,32 @@ class Participant: # check available Trades for confirmation and move them to the TradeQueue for t in self.availableTrades: if len(t.sig_chain[0]) > 0 and len(t.sig_chain[1]) > 0: + # here more verification should happen, but time is running out self.TradeQueue.append(t) self.availableTrades.remove(t) logger.info("===> trade with two signatures moved from available to Queue") async def enact_Trades(self): + # first move currently active trades to history + logger.info("===> enacting trades on " + self.publicIP.__str__()) + logger.info("===> trades in queue: " + len(self.TradeQueue).__str__()) + for t in self.activeTrades: + self.__tradeHistory.append(t) + self.activeTrades.remove(t) + logger.info("===> trade moved from active to history") for t in self.TradeQueue: - pass - # TODO: continue here - + logger.info("===> checking trade") + logger.info("???> offer: " + t.offer.publicIP.__str__() + " request: " + t.request.publicIP.__str__() + "self:" + self.publicIP.__str__()) + self.activeTrades.append(t) + if t.offer.publicKey == self.publicKey: + logger.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") + logger.info("===> now sending " + str(t.power) + " from " + t.request.publicIP.__str__()) + # now the hardware should be controlled to actually take the power from the grid + if t.request.publicKey == self.publicKey: + logger.info("+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++") + logger.info("===> now receiving " + str(t.power) + " to " + t.offer.publicIP.__str__()) + # now the hardware should be controlled to actually send the power to the grid + self.TradeQueue.remove(t) class Weather: