Skip to content
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

Abort ScheduleSignTransitionLogic if schedule is resolved #1303

Merged
merged 14 commits into from
Apr 30, 2021

Conversation

tinker-michaelj
Copy link
Collaborator

@tinker-michaelj tinker-michaelj commented Apr 22, 2021

Summary of the change:

  • Abort from ScheduleSignTransitionLogic if the target schedule is already resolved (either executed or deleted).
  • For extra safety, make ScheduleReadyForExecution gate the call to txnCtx.trigger by confirming the schedule was successfully marked as executed.

Also create tests that assert both response codes and state changes (including charged service fees for non-SUCCESSful transactions) are as expected when we:

  • Schedule an xfer with 3 separate senders, all with the same key
    • Confirm execution upon signing with this key
  • Schedule a submit message to a topic w/ submit key and designated payer, signing with designated payer
    • Change submit key on topic to match designated payer
    • Verify execution when submitting an empty ScheduleSign
  • Schedule a xfer with 1/3 sender using ScheduleCreate payer whose sig includes 1/3
    • Confirm immediate execution
    • Confirm no re-execution after signing with 2/3 and 3/3
  • Schedule a xfer with 1/3 sender and 1/1 receiverSigRequired using ScheduleCreate payer w/ unrelated sigs; confirm,
    • Confirm no execution after 1/3 sender signs
    • Confirm no execution after 2/3 sender signs
    • Confirm execution after 1/1 signs
    • Confirm no re-execution after 3/3 sender signs
  • Schedule a xfer with 1/3 sender and 1/1 receiverSigRequired using ScheduleCreate payer w/ unrelated sigs; confirm,
    • Confirm no execution after 1/1 signs
    • Confirm execution after 1/3 sender signs
    • Confirm no re-execution after 2/3 sender signs
    • Confirm no re-execution after 3/3 sender signs
  • Schedule a xfer with 2/{1/3, 1/3, 1/3} sender using ScheduleCreate payer whose sig includes one sig from first nested 1/3
    • Confirm no immediate execution
    • Confirm execution after signing with one sig from second nested 1/3
    • Confirm no re-execution after signing with one sig from third nested 1/3
  • Schedule a xfer with 2/{1/3, 1/3, 1/3} sender using ScheduleCreate payer whose sig includes one sig from first nested 1/3
    • Confirm no immediate execution
    • Update sender to have 2/{1/3, 1/3, 2/3}
    • Confirm no execution after signing with one sig from third nested 2/3
    • Confirm execution after signing with second sig from third nested 2/3
    • Confirm no re-execution after signing all three sigs from second nested 1/3
  • Schedule a xfer with 2/3 sender and receiver no sig required using ScheduleCreate whose sig includes one sig from 2/3
    • Confirm no immediate execution
    • Update receiver to have receiverSigRequired
    • Confirm no execution signing with second of sender 2/3
    • Confirm execution signing with receiver
    • Confirm no re-execution signing with third of sender 2/3
  • Confirm no execution of admin-deleted schedules
  • Trigger an xfer that fails with INSUFFICIENT_TXN_FEE
  • Trigger an xfer that fails with INVALID_ACCOUNT_AMOUNTS
  • Trigger an xfer that fails with TRANSFER_LIST_SIZE_EXCEEDED
  • Trigger an xfer that fails with TOKEN_TRANSFER_LIST_SIZE_EXCEEDED
  • Trigger an xfer that fails with INSUFFICIENT_PAYER_BALANCE
  • Trigger an xfer that fails with INSUFFICIENT_ACCOUNT_BALANCE (both hbar and token)
  • Trigger an xfer that fails with ACCOUNT_IS_DELETED
  • Trigger an xfer that fails with TOKEN_IS_DELETED
  • Trigger an xfer that fails with ACCOUNT_NOT_ASSOCIATED_TO_TOKEN
  • Trigger an xfer that fails with ACCOUNT_FROZEN_FOR_TOKEN
  • Trigger an xfer that fails with ACCOUNT_KYC_NOT_GRANTED_FOR_TOKEN
  • Trigger an xfer that fails with TRANSFERS_NOT_ZERO_SUM_FOR_TOKEN
  • Trigger an xfer that fails with TOKEN_ID_IS_REPEATED_IN_TOKEN_LIST
  • Trigger an xfer that fails with EMPTY_TOKEN_TRANSFER_ACCOUNT_AMOUNTS
  • Trigger a submit message that fails with MESSAGE_SIZE_TOO_LARGE
  • Confirm submit messages can no longer be triggered if their target topics is deleted (should get UNRESOLVABLE_REQUIRED_SIGNERS)
  • Trigger a submit message that fails with INVALID_CHUNK_NUMBER
  • Confirm submit message cannot be scheduled to a topic that doesn't exist (should get UNRESOLVABLE_REQUIRED_SIGNERS)
  • Trigger a submit message that fails with INVALID_CHUNK_TRANSACTION_ID

@codecov
Copy link

codecov bot commented Apr 22, 2021

Codecov Report

Merging #1303 (6722609) into master (ba21b64) will increase coverage by 0.00%.
The diff coverage is 97.43%.

Impacted file tree graph

@@            Coverage Diff            @@
##             master    #1303   +/-   ##
=========================================
  Coverage     87.89%   87.90%           
- Complexity     5672     5677    +5     
=========================================
  Files           450      450           
  Lines         16839    16858   +19     
  Branches       1757     1760    +3     
=========================================
+ Hits          14801    14819   +18     
- Misses         1567     1568    +1     
  Partials        471      471           
Impacted Files Coverage Δ Complexity Δ
...s/txns/schedule/ScheduleCreateTransitionLogic.java 94.73% <85.71%> (-1.16%) 18.00 <0.00> (ø)
...a/com/hedera/services/context/ServicesContext.java 95.06% <100.00%> (+0.04%) 259.00 <2.00> (+2.00)
...edera/services/txns/schedule/ScheduleExecutor.java 100.00% <100.00%> (ø) 3.00 <3.00> (?)
...ces/txns/schedule/ScheduleSignTransitionLogic.java 100.00% <100.00%> (ø) 13.00 <6.00> (+2.00)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ba21b64...6722609. Read the comment docs.

Copy link
Collaborator

@Daniel-K-Ivanov Daniel-K-Ivanov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

rbair23
rbair23 previously approved these changes Apr 27, 2021
public abstract class ScheduleReadyForExecution {
import static com.hederahashgraph.api.proto.java.ResponseCodeEnum.OK;

public class ScheduleReadyForExecution {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's add some class level documentation to explain what this class is and how it fits into the system

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added class level documentation here.

@@ -37,16 +39,19 @@
}

ResponseCodeEnum processExecution(ScheduleID id) throws InvalidProtocolBufferException {
var executionStatus = store.markAsExecuted(id);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer to see "final" in situations like this. It makes reading the code easier, because as I read the code (from top to bottom) I can tell just from this line that executionStatus isn't going to be modified anywhere further down. As it is, I'm not sure, so I have to read the rest of the code in the block scope to verify that it is "effectively final".

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Made the changes.

Comment on lines 32 to 40
/**
* Defines a class to handle scheduled transaction execution
* once the scheduled transaction is signed by the required
* number of parties.
*
* @author Michael Tinker
* @author Abhishek Pandey
*/
public class ScheduleReadyForExecution {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for adding some documentation.

I see that the class is non-final, yet the documentation doesn't give me any idea as to whether this is intentional or not. I don't want to see a comment that says something like "This class is non-final so it can be extended", but rather something like "This base class does X. Subclasses should override X, Y, and Z to implement ABC". Something with more meat to it. Or, if the class is not meant to be extended, lets forbid it by making the class final.

Another thought is that you can probably run the comment out to 80 chars instead of breaking at 60 or so.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe it could be made final and ScheduleCreateTransitionLogic, ScheduleSignTransitionLogic which extend from this class could use the base class instance as a member variable. Refactoring has introduced some unit tests failures for now which would be fixed with the help of @tinker-michaelj

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Refactored to use the new final class ScheduleExecutor, and modified the documentation comments to be around 80 chars.

Comment on lines 53 to 55
* @param id The id of the scheduled transaction.
*
* @return the response code from executing the inner scheduled transaction
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like us to document the expected state and conditions for the param and the return value. I see that id is an object, which means it might be null. Is null a valid input? How does it behave if we do pass a null? (Is there a test for this?).

The method documentation suggests that this method checks if the underlying transaction is already executed/deleted. Based on this wording, I would expect the method to return a boolean. But actually, I think this method does more, it just happens to perform this check in addition to other stuff? The method description doesn't seem to align with the method signature.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for reviewing it, I have changed the method documentation, added tests for not null checks. The inputs now have a @NotNull annotation. The return value would always be a proper ResponseEnumCode.

@abhishek-hedera abhishek-hedera force-pushed the handle-repeated-signings branch 2 times, most recently from e183d07 to d261578 Compare April 28, 2021 18:54
Comment on lines 40 to 51
/**
* Given a {@link ScheduleID}, {@link ScheduleStore}, {@link TransactionContext} it first checks if the underlying
* transaction is already executed/deleted before attempting to execute and then returns response code after
* triggering the underlying transaction. A ResponseEnumCode of OK is returned upon successful trigger of the
* inner transaction.
*
* @param id The id of the scheduled transaction.
* @param store Object to handle scheduled entity type.
* @param context Object to handle inner transaction specific context on a node.
* @return the response code {@link ResponseCodeEnum} from executing the inner scheduled transaction
*/
ResponseCodeEnum processExecution(ScheduleID id, ScheduleStore store, TransactionContext context) throws
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this documentation, it is much better! Please also add some indication as to whether the various args and return value can be null. Are we able to use the @NotNull annotation? That might make static code analysis able to interpret the semantics, and not just have it defined in the documentation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds great. Modified it to have @NotNull annotation.

@abhishek-hedera abhishek-hedera force-pushed the handle-repeated-signings branch from e0132a5 to 6722609 Compare April 30, 2021 20:42
@tinker-michaelj tinker-michaelj merged commit 711321f into master Apr 30, 2021
@tinker-michaelj tinker-michaelj deleted the handle-repeated-signings branch April 30, 2021 22:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants