-
Notifications
You must be signed in to change notification settings - Fork 976
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
cap-0018 - Implementation after removing low-level auth checks starting from v10 #2387
Conversation
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 a much cleaner implementation, much easier to review and reason about. I left a few small comments, although I haven't reviewed the new AllowTrust tests yet.
@@ -50,7 +50,7 @@ canSellAtMost(LedgerTxnHeader const& header, LedgerTxnEntry const& account, | |||
return std::max({getAvailableBalance(header, account), int64_t(0)}); | |||
} | |||
|
|||
if (trustLine && trustLine.isAuthorized()) | |||
if (trustLine && trustLine.isAuthorizedToMaintainLiabilities()) |
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.
Do we actually need to check authorization here at all starting from version 10? Same thing for the other overload.
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 a good point. We don't need to check as the authorization is checked prior to this for v10 and up. I did this because it looked cleaner than header.current().ledgerVersion >= 10 || trustLine.isAuthorized()
, but I think the intention is clearer if we only check the authorization pre v10. I'll make the change.
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.
just a few minor questions. not sure if you guys discussed defensive coding practices
4c10221
to
ead4492
Compare
ead4492
to
16d6d5a
Compare
16d6d5a
to
902b5bc
Compare
902b5bc
to
6ffe2ed
Compare
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 looks good. I left a few very minor comments on one of the tests. But I also had some thoughts while reviewing the PR that aren't necessarily specific to any single line:
- I'm not sure that the defensive programming approach that we took in this PR is the right one. I am of the opinion that, starting from protocol 10 (or maybe 13) we should throw if we reach
addBalance
,addBuyingLiabilities
, etc with!isAuthorizedToMaintainLiabilities
. I think this is the correct approach because we are already depending on the client code to check that it is correct betweenisAuthorizedToMaintainLiabilities
andisAuthorized
. If the client code has permitted those functions to be reached in the case mentioned above, then there is definitely a logic error. We shouldn't carry on processing the transaction if there is definitely a logic error, instead we should returntxINTERNAL_ERROR
. - We added defensive programming checks to
getMaxAmountReceive
but they are missing from the analogous functiongetAvailableBalance
(which didn't require any changes in this PR). - The changes in the first commit were based off of the assumption that we always check authorization before reaching those functions, but that isn't true on the path through
releaseLiabilities
(see, for example, ManageOfferOpFrameBase.cpp:224 and note that the offer loaded there does not necessarily have the same assets as specified in the operation). Now assuming that everything works correctly, this shouldn't cause any issues because an offer in the ledger should have authorized trust lines. But we took similar precautions at OfferExchange.cpp:1112.
cade8ee
to
89fe97f
Compare
I added a commit that throws if we reach those methods starting in protocol 10. I like this approach as the assumptions made are clear and enforced.
I added an authorization check in
This is an interesting scenario. The authorization shouldn't matter since |
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 an interesting scenario. The authorization shouldn't matter since releaseLiabilities is removing offers. However, if there are unauthorized offers in the ledger, we will throw in addBuyingLiabilities and addSellingLiabilities (with my latest change). Because of the new invariants, I think the check at OfferExchange.cpp:1112 is unnecessary because releaseLiabilities is called on the existing offer at OfferExchange.cpp:1100, which will do the auth check anyways. If you agree, I will remove the check on OfferExchange.cpp:1112.
Yes, I agree that the check on OfferExchange.cpp:1112 is unnecessary now. I think it would be worth adding a comment where releaseLiabilitites
is used on OfferExchange.cpp:1099 indicating that this is being checked there. Have you checked that everything makes sense at other places where releaseLiabilities
is used, such as AllowTrustOpFrame.cpp:135 (there are a few other places too)?
@@ -429,14 +448,18 @@ getAvailableBalance(LedgerTxnHeader const& header, LedgerEntry const& le) | |||
} | |||
else if (le.data.type() == TRUSTLINE) | |||
{ | |||
if (ledgerVersionMinV10 && !isAuthorizedToMaintainLiabilities(le)) |
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.
Any reason not to use checkAuthorization
here? I know you don't need the return value (so a comment about that would be warranted) but it looks like it would cover the throw
part correctly.
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 just thought it was easier to read this way. But using checkAuthorization
will work as well, and will allow us to keep the throw logic in one spot. I'll make the change.
89fe97f
to
8d6f542
Compare
Yeah the other |
8d6f542
to
1ca2deb
Compare
r+ 1ca2deb |
Description
Implements https://github.com/stellar/stellar-protocol/blob/master/core/cap-0018.md
Checklist
clang-format
v5.0.0 (viamake format
or the Visual Studio extension)