From 63fb0831db101a226a02ab022dd5c36ea7dd7c32 Mon Sep 17 00:00:00 2001 From: holgern <holgernahrstaedt@gmx.de> Date: Wed, 1 Apr 2020 22:48:41 +0200 Subject: [PATCH] Fix curation and author reward calculation --- .circleci/config.yml | 40 +++++++--------------------------------- CHANGELOG.rst | 2 ++ beem/account.py | 4 +--- beem/cli.py | 38 +++++++++++++++++++++++++------------- beem/comment.py | 15 +++++++++------ beem/vote.py | 7 ++++++- tox.ini | 2 +- 7 files changed, 51 insertions(+), 57 deletions(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 978aa795..55eca99e 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -56,9 +56,9 @@ jobs: # tox -e upload_coverage # fi - build-python2.7: + build-python3.8: docker: - - image: circleci/python:2.7 + - image: circleci/python:3.8 working_directory: ~/repo steps: - checkout @@ -77,30 +77,7 @@ jobs: - run: name: run tests command: | - tox -e py27 - - build-python3.4: - docker: - - image: circleci/python:3.4 - working_directory: ~/repo - steps: - - checkout - # Download and cache dependencies - - restore_cache: - keys: - - v1-dependencies-{{ checksum "requirements-test.txt" }} - # fallback to using the latest cache if no exact match is found - - v1-dependencies- - - run: - name: install dependencies - command: | - sudo python -m pip install --upgrade -r requirements-test.txt - sudo python -m pip install --upgrade secp256k1 - - - run: - name: run tests - command: | - tox -e py34 + tox -e py38 build-python3.5: docker: @@ -150,15 +127,12 @@ workflows: build: jobs: - build-python3.6 - - build-python2.7: - requires: - - build-python3.6 - - build-python3.4: - requires: - - build-python2.7 - build-python3.5: requires: - - build-python3.4 + - build-python3.6 - build-python3.7: requires: - build-python3.5 + - build-python3.8: + requires: + - build-python3.7 diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 758b0d30..45e13142 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -9,6 +9,8 @@ Changelog * Discussions has been fixed * raw_data parameter added to all discussions * beempy curation, beempy votes and beempy pending has been fixed +* Votes table improved +* fix curation and author reward calculation 0.22.11 ------- diff --git a/beem/account.py b/beem/account.py index c7de1357..b5197f55 100644 --- a/beem/account.py +++ b/beem/account.py @@ -1513,7 +1513,7 @@ class Account(BlockchainObject): else: return self.steem.rpc.get_expiring_vesting_delegations(account, formatTimeString(after), limit) - def get_account_votes(self, account=None): + def get_account_votes(self, account=None, start_author="", start_permlink=""): """ Returns all votes that the account has done :rtype: list @@ -1543,8 +1543,6 @@ class Account(BlockchainObject): # vote_list = self.steem.rpc.get_account_votes(account) # if isinstance(vote_list, dict) and "error" in vote_list: self.steem.rpc.set_next_node_on_empty_reply(True) - start_author = "" - start_permlink = "" vote_list = [] finished = False while not finished: diff --git a/beem/cli.py b/beem/cli.py index bfe9f0c7..85d6217e 100644 --- a/beem/cli.py +++ b/beem/cli.py @@ -33,7 +33,7 @@ from beem.asset import Asset from beem.witness import Witness, WitnessesRankedByVote, WitnessesVotedByAccount from beem.blockchain import Blockchain from beem.utils import formatTimeString, construct_authorperm, derive_beneficiaries, derive_tags, seperate_yaml_dict_from_body -from beem.vote import AccountVotes, ActiveVotes +from beem.vote import AccountVotes, ActiveVotes, Vote from beem import exceptions from beem.version import version as __version__ from beem.asciichart import AsciiChart @@ -2516,7 +2516,9 @@ def votes(account, direction, outgoing, incoming, days, export): account = Account(account, steem_instance=stm) votes_list = [] for v in account.history(start=limit_time, only_ops=["vote"]): - votes_list.append(v) + vote = Vote(v, steem_instance=stm) + vote.refresh() + votes_list.append(vote) votes = ActiveVotes(votes_list, steem_instance=stm) in_votes_str = votes.printAsTable(votee=account["name"], return_str=True) if export: @@ -2567,13 +2569,13 @@ def curation(authorperm, account, limit, min_vote, max_vote, min_performance, ma if not account: account = stm.config["default_account"] utc = pytz.timezone('UTC') - limit_time = utc.localize(datetime.utcnow()) - timedelta(days=days) + limit_time = utc.localize(datetime.utcnow()) - timedelta(days=7) votes = AccountVotes(account, start=limit_time, steem_instance=stm) - authorperm_list = [Comment(vote.authorperm, steem_instance=stm) for vote in votes] + authorperm_list = [vote.authorperm for vote in votes] if authorperm.isdigit(): if len(authorperm_list) < int(authorperm): raise ValueError("Authorperm id must be lower than %d" % (len(authorperm_list) + 1)) - authorperm_list = [authorperm_list[int(authorperm) - 1]["authorperm"]] + authorperm_list = [authorperm_list[int(authorperm) - 1]] all_posts = False else: all_posts = True @@ -2937,8 +2939,9 @@ def rewards(accounts, only_sum, post, comment, curation, length, author, permlin @click.option('--author', '-a', help='Show the author for each entry', is_flag=True, default=False) @click.option('--permlink', '-e', help='Show the permlink for each entry', is_flag=True, default=False) @click.option('--title', '-t', help='Show the title for each entry', is_flag=True, default=False) -@click.option('--days', '-d', default=1., help="Limit shown rewards by this amount of days (default: 1), max is 7 days.") -def pending(accounts, only_sum, post, comment, curation, length, author, permlink, title, days): +@click.option('--days', '-d', default=7., help="Limit shown rewards by this amount of days (default: 7), max is 7 days.") +@click.option('--from', '-f', '_from', default=0., help="Start day from which on rewards are shown (default: 0), max is 7 days.") +def pending(accounts, only_sum, post, comment, curation, length, author, permlink, title, days, _from): """ Lists pending rewards """ stm = shared_steem_instance() @@ -2953,12 +2956,20 @@ def pending(accounts, only_sum, post, comment, curation, length, author, permlin days = 1 if days > 7: days = 7 + if _from < 0: + _from = 0 + if _from > 7: + _from = 7 + if _from + days > 7: + days = 7 - _from sp_symbol = "SP" if stm.is_hive: sp_symbol = "HP" utc = pytz.timezone('UTC') - limit_time = utc.localize(datetime.utcnow()) - timedelta(days=days) + max_limit_time = utc.localize(datetime.utcnow()) - timedelta(days=7) + limit_time = utc.localize(datetime.utcnow()) - timedelta(days=_from + days) + start_time = utc.localize(datetime.utcnow()) - timedelta(days=_from) for account in accounts: sum_reward = [0, 0, 0, 0] account = Account(account, steem_instance=stm) @@ -2981,10 +2992,11 @@ def pending(accounts, only_sum, post, comment, curation, length, author, permlin rows = [] c_list = {} start_op = account.estimate_virtual_op_num(limit_time) + stop_op = account.estimate_virtual_op_num(start_time) if start_op > 0: start_op -= 1 - progress_length = (account.virtual_op_count() - start_op) / 1000 - with click.progressbar(map(Comment, account.history(start=start_op, use_block_num=False, only_ops=["comment"])), length=progress_length) as comment_hist: + progress_length = (stop_op - start_op) / 1000 + with click.progressbar(map(Comment, account.history(start=start_op, stop=stop_op, use_block_num=False, only_ops=["comment"])), length=progress_length) as comment_hist: for v in comment_hist: try: v.refresh() @@ -3021,20 +3033,20 @@ def pending(accounts, only_sum, post, comment, curation, length, author, permlin permlink_row = v.permlink rows.append([v["author"], permlink_row, - ((v["created"] - limit_time).total_seconds() / 60 / 60 / 24), + ((v["created"] - max_limit_time).total_seconds() / 60 / 60 / 24), (payout_SBD), (payout_SP), (liquid_USD), (invested_USD)]) if curation: - votes = AccountVotes(account, start=limit_time, steem_instance=stm) + votes = AccountVotes(account, start=limit_time, stop=start_time, steem_instance=stm) for vote in votes: authorperm = construct_authorperm(vote["author"], vote["permlink"]) c = Comment(authorperm, steem_instance=stm) rewards = c.get_curation_rewards() if not rewards["pending_rewards"]: continue - days_to_payout = ((c["created"] - limit_time).total_seconds() / 60 / 60 / 24) + days_to_payout = ((c["created"] - max_limit_time).total_seconds() / 60 / 60 / 24) if days_to_payout < 0: continue payout_SP = rewards["active_votes"][account["name"]] diff --git a/beem/comment.py b/beem/comment.py index cd368545..0fb8c5fe 100644 --- a/beem/comment.py +++ b/beem/comment.py @@ -354,7 +354,7 @@ class Comment(BlockchainObject): return K * vote_value_SBD * t * math.sqrt(estimated_value_SBD) def get_curation_penalty(self, vote_time=None): - """ If post is less than 15 minutes old, it will incur a curation + """ If post is less than 5 minutes old, it will incur a curation reward penalty. :param datetime vote_time: A vote time can be given and the curation @@ -453,6 +453,8 @@ class Comment(BlockchainObject): def get_author_rewards(self): """ Returns the author rewards. + + Example:: { @@ -468,12 +470,12 @@ class Comment(BlockchainObject): "payout_SP": Amount(0, self.steem.steem_symbol, steem_instance=self.steem), "payout_SBD": Amount(0, self.steem.sbd_symbol, steem_instance=self.steem), "total_payout_SBD": Amount(self["total_payout_value"], steem_instance=self.steem)} - + author_reward_factor = 0.5 median_hist = self.steem.get_current_median_history() if median_hist is not None: median_price = Price(median_hist, steem_instance=self.steem) beneficiaries_pct = self.get_beneficiaries_pct() - curation_tokens = self.reward * 0.25 + curation_tokens = self.reward * author_reward_factor author_tokens = self.reward - curation_tokens curation_rewards = self.get_curation_rewards() if self.steem.hardfork >= 20 and median_hist is not None: @@ -490,7 +492,7 @@ class Comment(BlockchainObject): return {'pending_rewards': True, "total_payout": author_tokens} def get_curation_rewards(self, pending_payout_SBD=False, pending_payout_value=None): - """ Returns the curation rewards. + """ Returns the curation rewards. The split between creator/curator is currently 50%/50%. :param bool pending_payout_SBD: If True, the rewards are returned in SBD and not in STEEM (default is False) :param pending_payout_value: When not None this value instead of the current @@ -523,6 +525,7 @@ class Comment(BlockchainObject): median_price = Price(median_hist, steem_instance=self.steem) pending_rewards = False active_votes_list = self.get_votes() + curator_reward_factor = 0.5 if "total_vote_weight" in self: total_vote_weight = self["total_vote_weight"] @@ -551,9 +554,9 @@ class Comment(BlockchainObject): elif isinstance(pending_payout_value, str): pending_payout_value = Amount(pending_payout_value, steem_instance=self.steem) if pending_payout_SBD or median_hist is None: - max_rewards = (pending_payout_value * 0.25) + max_rewards = (pending_payout_value * curator_reward_factor) else: - max_rewards = median_price.as_base(self.steem.steem_symbol) * (pending_payout_value * 0.25) + max_rewards = median_price.as_base(self.steem.steem_symbol) * (pending_payout_value * curator_reward_factor) unclaimed_rewards = max_rewards.copy() pending_rewards = True diff --git a/beem/vote.py b/beem/vote.py index 93491977..96927156 100644 --- a/beem/vote.py +++ b/beem/vote.py @@ -259,12 +259,15 @@ class VotesObject(list): if (start is None or d_time >= start) and (stop is None or d_time <= stop) and\ (start_percent is None or percent >= start_percent) and (stop_percent is None or percent <= stop_percent) and\ (voter is None or vote["voter"] == voter) and (votee is None or vote.votee == votee): + percent = vote.get('percent', '') + if percent == '': + percent = vote.get('vote_percent', '') t.add_row([vote['voter'], vote.votee, str(round(vote.sbd, 2)).ljust(5) + "$", timestr, vote.get("rshares", ""), - str(vote.get('percent', '')), + str(percent), str(vote['weight'])]) if return_str: @@ -282,6 +285,8 @@ class VotesObject(list): start = None stop = None percent = vote.get('percent', '') + if percent == '': + percent = vote.get('vote_percent', '') if percent == '': start_percent = None stop_percent = None diff --git a/tox.ini b/tox.ini index 5e8d759d..0a4350ae 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,34,35,36,37} +envlist = py{27,35,36,37,38} skip_missing_interpreters = true [testenv] -- GitLab