Skip to content

Commit

Permalink
Merge pull request tezos-reward-distributor-organization#138 from hab…
Browse files Browse the repository at this point in the history
…anoz/development

Development
  • Loading branch information
habanoz authored Nov 30, 2019
2 parents 228c3a6 + 2939ad8 commit 2d5fb37
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 23 deletions.
1 change: 1 addition & 0 deletions examples/email.ini
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ smtp.host =
smtp.port =
sender =
recipients =
use_ssl=
17 changes: 13 additions & 4 deletions src/emails/email_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
HOST = "smtp.host"
PORT = "smtp.port"
SENDER = "sender"
USE_SSL = "use.ssl"

EMAIL_INI_PATH = "./email.ini"

Expand All @@ -29,13 +30,22 @@ def __init__(self):

config.read(EMAIL_INI_PATH)
default = config['DEFAULT']

use_ssl = self.getUseSslOrFalse(default)

self.default = default
if self.all_set(default):
self.email_sender = EmailSender(default[HOST], int(default[PORT]), default[USER],
default[PASS], default[SENDER])
self.email_sender = EmailSender(default[HOST], int(default[PORT]), default[USER], default[PASS],
default[SENDER], use_ssl)
else:
logger.info("If you want to send emails, populate email.ini file under current working directory.")

def getUseSslOrFalse(self, default):
use_ssl = False
if USE_SSL in default:
use_ssl = default[USE_SSL]
return use_ssl

def all_set(self, default):
return default[USER] and default[PASS] and default[HOST] and default[PORT] and default[SENDER] and default[
RECIPIENTS]
Expand All @@ -46,7 +56,7 @@ def check_and_create_ini(self):

with open(EMAIL_INI_PATH, "w") as f:
f.writelines(["[DEFAULT]\n", USER + NL, PASS + NL, HOST + NL, PORT + NL, SENDER + NL,
RECIPIENTS + NL])
RECIPIENTS + NL + USE_SSL+NL])

def send_payment_mail(self, cyle, payments_file, nb_failed, nb_unknown):
if not self.email_sender:
Expand All @@ -60,4 +70,3 @@ def send_payment_mail(self, cyle, payments_file, nb_failed, nb_unknown):
self.default["recipients"], [payments_file])

logger.debug("Report email sent for cycle {}.".format(cyle))

14 changes: 12 additions & 2 deletions src/emails/email_worker.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,9 @@


class EmailSender():
def __init__(self, host, port, user, passw, sender):
def __init__(self, host, port, user, passw, sender, use_ssl: False):
super(EmailSender, self).__init__()
self.use_ssl = use_ssl
self.host = host
self.port = port
self.sender = sender
Expand Down Expand Up @@ -36,7 +37,16 @@ def send(self, title, message, recipients, attachments):
part['Content-Disposition'] = 'attachment; filename="%s"' % basename(f)
msg.attach(part)

smtp = smtplib.SMTP(self.host, self.port)
if self.use_ssl:
smtp = smtplib.SMTP_SSL(self.host, self.port)
else:
smtp = smtplib.SMTP(self.host, self.port)

smtp.login(self.user, self.password)
smtp.sendmail(self.sender, recipient_string, msg.as_string())
smtp.close()


if __name__ == '__main__':
sender = EmailSender("---", 587, "---", "---", "---")
sender.send("---", "---", "---", [])
54 changes: 37 additions & 17 deletions src/rpc/rpc_reward_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@


class RpcRewardApiImpl(RewardApi):

COMM_HEAD = "{}/chains/main/blocks/head"
COMM_DELEGATES = "{}/chains/main/blocks/{}/context/delegates/{}"
COMM_BLOCK = "{}/chains/main/blocks/{}"
Expand Down Expand Up @@ -47,13 +46,17 @@ def get_rewards_for_cycle_map(self, cycle):
logger.debug("Current level {}, current cycle {}".format(current_level, current_cycle))

reward_data = {}
reward_data["delegate_staking_balance"], reward_data["delegators"] = self.__get_delegators_and_delgators_balance(cycle, current_level)
reward_data["delegate_staking_balance"], reward_data[
"delegators"] = self.__get_delegators_and_delgators_balance(cycle, current_level)
reward_data["delegators_nb"] = len(reward_data["delegators"])

# Get last block in cycle where rewards are unfrozen
level_of_last_block_in_unfreeze_cycle = (cycle+self.preserved_cycles+1) * self.blocks_per_cycle
level_of_last_block_in_unfreeze_cycle = (cycle + self.preserved_cycles + 1) * self.blocks_per_cycle

logger.debug("Cycle {}, preserved cycles {}, blocks per cycle {}, last_block_cycle {}".format(cycle, self.preserved_cycles, self.blocks_per_cycle, level_of_last_block_in_unfreeze_cycle))
logger.debug("Cycle {}, preserved cycles {}, blocks per cycle {}, last_block_cycle {}".format(cycle,
self.preserved_cycles,
self.blocks_per_cycle,
level_of_last_block_in_unfreeze_cycle))

if current_level - level_of_last_block_in_unfreeze_cycle >= 0:
unfrozen_rewards = self.__get_unfrozen_rewards(level_of_last_block_in_unfreeze_cycle, cycle)
Expand All @@ -63,9 +66,11 @@ def get_rewards_for_cycle_map(self, cycle):
logger.warn("Please wait until the rewards and fees for cycle {} are unfrozen".format(cycle))
reward_data["total_rewards"] = 0

reward_model = RewardProviderModel(reward_data["delegate_staking_balance"], reward_data["total_rewards"], reward_data["delegators"])
reward_model = RewardProviderModel(reward_data["delegate_staking_balance"], reward_data["total_rewards"],
reward_data["delegators"])

logger.debug("delegate_staking_balance={}, total_rewards = {}".format(reward_data["delegate_staking_balance"],reward_data["total_rewards"]))
logger.debug("delegate_staking_balance={}, total_rewards = {}".format(reward_data["delegate_staking_balance"],
reward_data["total_rewards"]))
logger.debug("delegators = {}".format(reward_data["delegators"]))

return reward_model
Expand All @@ -83,24 +88,29 @@ def __get_unfrozen_rewards(self, level_of_last_block_in_unfreeze_cycle, cycle):
if int(balance_update["cycle"]) == cycle or int(balance_update["change"]) < 0:
if balance_update["category"] == "rewards":
unfrozen_rewards = -int(balance_update["change"])
logger.debug("[__get_unfrozen_rewards] Found balance update for reward {}".format(balance_update))
logger.debug(
"[__get_unfrozen_rewards] Found balance update for reward {}".format(balance_update))
elif balance_update["category"] == "fees":
unfrozen_fees = -int(balance_update["change"])
logger.debug("[__get_unfrozen_rewards] Found balance update for fee {}".format(balance_update))
logger.debug(
"[__get_unfrozen_rewards] Found balance update for fee {}".format(balance_update))
else:
logger.debug("[__get_unfrozen_rewards] Found balance update, not including: {}".format(balance_update))
logger.debug("[__get_unfrozen_rewards] Found balance update, not including: {}".format(
balance_update))
else:
logger.debug("[__get_unfrozen_rewards] Found balance update, cycle does not match or change is non-zero, not including: {}".format(balance_update))
logger.debug(
"[__get_unfrozen_rewards] Found balance update, cycle does not match or change is non-zero, not including: {}".format(
balance_update))

return unfrozen_fees + unfrozen_rewards

def do_rpc_request(self, request):
def do_rpc_request(self, request, time_out=120):
if self.verbose:
logger.debug("[do_rpc_request] Requesting URL {}".format(request))

sleep(0.1) # be nice to public node service
sleep(0.1) # be nice to public node service

resp = requests.get(request)
resp = requests.get(request, timeout=time_out)
if resp.status_code != 200:
raise Exception("Request '{} failed with status code {}".format(request, resp.status_code))

Expand All @@ -117,8 +127,6 @@ def __get_current_level(self):

return current_level, current_cycle



def __get_delegators_and_delgators_balance(self, cycle, current_level):

hash_snapshot_block = self.__get_snapshot_block_hash(cycle, current_level)
Expand All @@ -138,6 +146,17 @@ def __get_delegators_and_delgators_balance(self, cycle, current_level):
for idx, delegator in enumerate(delegators_addresses):
request = self.COMM_DELEGATE_BALANCE.format(self.node_url, hash_snapshot_block, delegator)
response = self.do_rpc_request(request)

sleep(0.5) # be nice to public node service

response = None

while not response:
try:
response = self.do_rpc_request(request, time_out=5)
except:
logger.error("Fetching delegator info failed {}, will retry", delegator)

delegators[delegator] = int(response["balance"])

logger.debug(
Expand All @@ -151,7 +170,7 @@ def __get_delegators_and_delgators_balance(self, cycle, current_level):
def __get_snapshot_block_hash(self, cycle, current_level):

snapshot_level = (cycle - self.preserved_cycles) * self.blocks_per_cycle + 1
logger.debug("Reward cycle {}, snapshot level {}".format(cycle,snapshot_level))
logger.debug("Reward cycle {}, snapshot level {}".format(cycle, snapshot_level))

block_level = cycle * self.blocks_per_cycle + 1

Expand All @@ -165,7 +184,8 @@ def __get_snapshot_block_hash(self, cycle, current_level):
logger.error("Too few or too many possible snapshots found!")
return ""

level_snapshot_block = (cycle - self.preserved_cycles - 2) * self.blocks_per_cycle + (chosen_snapshot+1) * self.blocks_per_roll_snapshot
level_snapshot_block = (cycle - self.preserved_cycles - 2) * self.blocks_per_cycle + (
chosen_snapshot + 1) * self.blocks_per_roll_snapshot
return level_snapshot_block

else:
Expand Down

0 comments on commit 2d5fb37

Please sign in to comment.