-
Notifications
You must be signed in to change notification settings - Fork 712
Make access to Nakamoto staging blocks restricted to one single pub fn #6585
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
Make access to Nakamoto staging blocks restricted to one single pub fn #6585
Conversation
…ntry Signed-off-by: Jacinta Ferrant <[email protected]>
Signed-off-by: Jacinta Ferrant <[email protected]>
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.
LGTM, and looks a lot safer too. Thanks!
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 really like this PR. It clarifies a lot of aspects around the block storage logic and introduces a clear single entry point for it. Great work on that part!
That said, I have some concerns about moving more business logic into the database layer.
In my view, the DB layer should primarily expose CRUD operations and enforce data integrity (for example, the methods made private in this PR fit well within that responsibility). However, with this change, the DB layer seems to have gained some additional business responsibilities.
This also has implications:
- Maybe less clarity on which layer we should write business logic.
- NakamotoChainState tests now depend (explicitly) on the DB layer’s business logic to run correctly.
- Testing the DB itself becomes a bit more trickier (considering our test organization), since some CRUD methods are now private, we can only test DB behavior indirectly through its business methods (or integration tests). Of course, we could still work around this by adding tests in the same module or child module, requiring different test organization.
To be clear, I’m not suggesting we block this PR. I think the direction is overall positive. I just wanted to open a discussion on this point, since we have similar situations in other DB implementations, and it might be worth aligning on a common approach.
I had the same thought while writing this PR. I hink its better to make the DB operations independent of chainstate logic, but was having a hard time enforcing the privacy restrictions i wanted as a result/I wanted to quickly prove that accept_block was truly the only point of insertion into the db. I do think its worth revisiting/additional effort to enforce better separation while keeping tighter restrictions on the db access. Let me see what I can do today cause I prob didn't give it enough thought. |
Can you elaborate more on this point? What business logic features do you believe are present in the database layer that could be moved out? |
I was thinking specifically store_block_if_better (which mostly calls already existing db functions though). However it does have logic around orphaned blocks, signing weight, etc. that seem a bit like they shouldn't be in the db transaction? But not sure how else to set this up. I would expect the outer caller to do these sorts of checks but then it means exposing all those inner db calls...so this is why I ended up where I ended up |
Right -- |
I think the current factoring was primarily driven by the goal of centralizing this piece of business logic, which is definitely a good direction. My main concern is simply where we choose to place this centralized logic. In my view, deciding whether one block is “better” than another shouldn’t be the DB’s responsibility, because that logic could evolve in future epochs. This effectively gives the DB two distinct “reasons to change” (one business-related, one data-related) which can blur its purpose. As @jferrant mentioned, it might be that for now the only practical place to host this logic (due to code constraints) is within the transaction layer. I assume because of the dependency with More broadly, beyond this specific function, what concerns me most is that it’s not fully clear (at least to me) where this kind of logic is expected to live going forward. For example:
To illustrate what I mean about boundary clarity:
Overall, these boundaries feel a bit opaque, which can make the code harder to reason about and maintain, at least from my current understanding of the system. That said, this PR is still a solid improvement and a positive step forward. Happy to continue this conversation if others have additional thoughts. |
… into chore/limit-staging-blocks-db-access
Signed-off-by: Jacinta Ferrant <[email protected]>
7762d88
Codecov Report❌ Patch coverage is
❌ Your project status has failed because the head coverage (77.09%) is below the target coverage (80.00%). You can increase the head coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## develop #6585 +/- ##
===========================================
+ Coverage 76.19% 77.09% +0.89%
===========================================
Files 571 571
Lines 351593 351577 -16
===========================================
+ Hits 267882 271032 +3150
+ Misses 83711 80545 -3166
... and 98 files with indirect coverage changes Continue to review full report in Codecov by Sentry.
🚀 New features to boost your workflow:
|
|
This pull request has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
As part of AAC, determined the desired code path to test should be
accept_block(which is called in the p2p_broadcast function for miners, and inprocess_new_nakamoto_block_extin the Relayer) and that these seemed to be the only points of entry to the staging blocks db. This PR just makes it clear that this is actually the case by making all other writing function calls private in nakamoto block staging db.Confirmed that calling
store_block_if_betteron a shadow block has the same effect as just doingstore_block. Therefore, we can use it as the single point of entry. I also updated theNakamotoChainState::accept_blockfn sig to be a bit more clear (at least to me), but I can revert that if the old fn sig is preferred.