-
Notifications
You must be signed in to change notification settings - Fork 2k
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
Fee Rate Improvements Part 1 #17668
base: main
Are you sure you want to change the base?
Fee Rate Improvements Part 1 #17668
Conversation
This pull request has conflicts, please resolve those before we can evaluate the pull request. |
Conflicts have been resolved. A maintainer will review the pull request shortly. |
|
Pull Request Test Coverage Report for Build 8422161012Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
@aqk There is a lot of coverage missing here - I think that needs to be fixed before this can get merged in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
first thoughts
MEMPOOL_CONSIDERED_FULL_RATIO = 0.8 | ||
|
||
|
||
class FeeStore: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make this a dataclass.
self.db_wrapper = db_wrapper | ||
|
||
# REVIEW: Should we use two tables: one for mempool data, one for estimates? | ||
async with self.db_wrapper.writer_maybe_transaction() as conn: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wouldn't think we need the 'maybe' form here. I think that is mostly for performance critical cases?
Generally we call this a writer
so it is clear what you are using at the call sites.
async with self.db_wrapper.writer_maybe_transaction() as writer:
clvm_cost: CLVMCost | ||
|
||
def get_rate_as_float(self) -> float: | ||
return float(self.mojos) / float(self.clvm_cost) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
>>> 3 / 2
1.5
Minor, but shouldn't need to float()
these.
return float(self.mojos) / float(self.clvm_cost) | |
return self.mojos / self.clvm_cost |
from chia.util.streamable import Streamable, streamable | ||
|
||
|
||
@typing_extensions.final |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is fine and we don't have a policy (I haven't even identified my own personal preference solidly yet) around when we do and don't use the extensions/backport modules, but... final
is available from stdlib typing
in all Python versions we support now. Leave as is or change as you prefer.
|
||
""" | ||
|
||
MINUTES_IN_WEEK = 1440 * 7 * 60 # Approximate number of entries to keep |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the 1440 was left over from some other calculation perhaps?
MINUTES_IN_WEEK = 1440 * 7 * 60 # Approximate number of entries to keep | |
MINUTES_IN_WEEK = 7 * 24 * 60 # Approximate number of entries to keep |
Or even start with the seconds first using datetime.timedelta(weeks=1).total_seconds()
. Maybe. Maybe not. I dislike the stdlib time features sufficiently that I would probably just type out the numbers.
# Approximate number of entries to keep
Is this because 18.75 seconds per block and ... do we have one transaction block for every three blocks? on average? I would personally find an actual calculation easier to follow since we (should?) have constants for the block rates. If my guessing there was even correct.
if row is not None: | ||
|
||
return self._row_to_fee_record(row) | ||
logging.getLogger(__name__).error(f"Dumping whole DB: {str()}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs changed multiple places. Should probably also report what error as well as actually outputting something. Or delete.
logging.getLogger(__name__).error(f"Dumping whole DB: {str()}") | |
self.log.error(f"Dumping whole DB: {str()}") |
def _row_to_fee_record(cls, row: sqlite3.Row) -> FeeRecord: | ||
return FeeRecord.from_bytes(row[0]) # cast: mypy limitation | ||
|
||
async def get_fee_record(self, key: FeeRecordKey) -> Optional[FeeRecord]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this expected to need to check non-existence a lot? If not, perhaps just raising an exception when you request a not-present data point might be better.
logging.getLogger(__name__).error(f"Dumping whole DB: {str()}") | ||
return None | ||
|
||
async def get_fee_record2(self, key: FeeRecordKey) -> Optional[FeeRecord]: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we need two methods, it would be good to clarify the difference better than 2
. (I expect this is part of a temporary exploration or somesuch)
async def prune(self) -> None: | ||
"""Delete records older than SECONDS_IN_WEEK""" | ||
async with self.db_wrapper.writer_maybe_transaction() as conn: | ||
now_secs = time.time() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You may want to make the clock callable be an attribute so that you can more readily test things like this.
cursor = await conn.execute("DELETE FROM fee_records WHERE block_index>?", (block_index,)) | ||
await cursor.close() | ||
|
||
async def prune(self) -> None: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably ought to be able to specify the age and/or time. Maybe two separate methods? I'm not exactly sure offhand what the best interface is here.
This PR has been flagged as stale due to no activity for over 60 days. It will not be automatically closed, but it has been given a stale-pr label and should be manually reviewed by the relevant parties. |
Purpose:
Current Behavior:
New Behavior:
Testing Notes: