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

HIP-423: Long Term Scheduled Transactions #2123

Merged
merged 7 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
run: ./gradlew checkAllModuleInfo --continue --scan

- name: Start Local Node
run: npx @hashgraph/hedera-local start -d --network local
run: npx @hashgraph/hedera-local start -d --network local --network-tag=0.57.0-alpha.0
0xivanov marked this conversation as resolved.
Show resolved Hide resolved

- name: Run Unit and Integration Tests
env:
Expand Down Expand Up @@ -150,7 +150,7 @@ jobs:
run: ./gradlew -p example-android assemble --scan

- name: Start the local node
run: npx @hashgraph/hedera-local start -d --network local
run: npx @hashgraph/hedera-local start -d --network local --network-tag=0.57.0-alpha.0

- name: Prepare .env for Examples
run: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,12 @@ public enum RequestType {
/**
* Submit a vote as part of the Threshold Signature Scheme (TSS) processing.
*/
TSS_VOTE(HederaFunctionality.TssVote);
TSS_VOTE(HederaFunctionality.TssVote),

/**
* Submit a node signature as part of the Threshold Signature Scheme (TSS) processing.
*/
TSS_SHARE_SIGNATURE(HederaFunctionality.TssShareSignature);

final HederaFunctionality code;

Expand Down Expand Up @@ -536,6 +541,7 @@ static RequestType valueOf(HederaFunctionality code) {
case TokenClaimAirdrop -> TOKEN_CLAIM_AIRDROP;
case TssMessage -> TSS_MESSAGE;
case TssVote -> TSS_VOTE;
case TssShareSignature -> TSS_SHARE_SIGNATURE;
default -> throw new IllegalStateException("(BUG) unhandled HederaFunctionality");
};
}
Expand Down Expand Up @@ -627,6 +633,7 @@ public String toString() {
case TOKEN_CLAIM_AIRDROP -> "TOKEN_CLAIM_AIRDROP";
case TSS_MESSAGE -> "TSS_MESSAGE";
case TSS_VOTE -> "TSS_VOTE";
case TSS_SHARE_SIGNATURE -> "TSS_SHARE_SIGNATURE";
};
}
}
39 changes: 38 additions & 1 deletion sdk/src/main/java/com/hedera/hashgraph/sdk/Status.java
Original file line number Diff line number Diff line change
Expand Up @@ -1749,7 +1749,39 @@ public enum Status {
* The client SHOULD query mirror node to determine the status of the pending
* airdrop and whether the sender can fulfill the offer.
*/
INVALID_TOKEN_IN_PENDING_AIRDROP(ResponseCodeEnum.INVALID_TOKEN_IN_PENDING_AIRDROP);
INVALID_TOKEN_IN_PENDING_AIRDROP(ResponseCodeEnum.INVALID_TOKEN_IN_PENDING_AIRDROP),

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time not strictly after the time at which its creation reached
* consensus.
*/
SCHEDULE_EXPIRY_MUST_BE_FUTURE(ResponseCodeEnum.SCHEDULE_EXPIRY_MUST_BE_FUTURE),

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time too far in the future after the time at which its creation
* reached consensus.
*/
SCHEDULE_EXPIRY_TOO_LONG(ResponseCodeEnum.SCHEDULE_EXPIRY_TOO_LONG),
0xivanov marked this conversation as resolved.
Show resolved Hide resolved

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time at which there is already too many transactions scheduled to
* expire; its creation must be retried with a different expiry.
*/
SCHEDULE_EXPIRY_IS_BUSY(ResponseCodeEnum.SCHEDULE_EXPIRY_IS_BUSY),

/**
* The provided gRPC certificate hash is invalid.
*/
INVALID_GRPC_CERTIFICATE_HASH(ResponseCodeEnum.INVALID_GRPC_CERTIFICATE_HASH),

/**
* A scheduled transaction configured to wait for expiry to execute was not
* given an explicit expiration time.
*/
MISSING_EXPIRY_TIME(ResponseCodeEnum.MISSING_EXPIRY_TIME);

final ResponseCodeEnum code;

Expand Down Expand Up @@ -2087,6 +2119,11 @@ static Status valueOf(ResponseCodeEnum code) {
case INVALID_PENDING_AIRDROP_ID -> INVALID_PENDING_AIRDROP_ID;
case TOKEN_AIRDROP_WITH_FALLBACK_ROYALTY -> TOKEN_AIRDROP_WITH_FALLBACK_ROYALTY;
case INVALID_TOKEN_IN_PENDING_AIRDROP -> INVALID_TOKEN_IN_PENDING_AIRDROP;
case SCHEDULE_EXPIRY_MUST_BE_FUTURE -> SCHEDULE_EXPIRY_MUST_BE_FUTURE;
case SCHEDULE_EXPIRY_TOO_LONG -> SCHEDULE_EXPIRY_TOO_LONG;
case SCHEDULE_EXPIRY_IS_BUSY -> SCHEDULE_EXPIRY_IS_BUSY;
case INVALID_GRPC_CERTIFICATE_HASH -> INVALID_GRPC_CERTIFICATE_HASH;
case MISSING_EXPIRY_TIME -> MISSING_EXPIRY_TIME;
case UNRECOGNIZED ->
// NOTE: Protobuf deserialization will not give us the code on the wire
throw new IllegalArgumentException(
Expand Down
7 changes: 6 additions & 1 deletion sdk/src/main/proto/basic_types.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1246,7 +1246,7 @@ enum HederaFunctionality {
TokenCancelAirdrop = 94;

/**
* Claim one or more pending airdrops
* Claim one or more pending airdrops
*/
TokenClaimAirdrop = 95;

Expand All @@ -1259,6 +1259,11 @@ enum HederaFunctionality {
* Submit a vote as part of the Threshold Signature Scheme (TSS) processing.
*/
TssVote = 97;

/**
* Submit a node signature as part of the Threshold Signature Scheme (TSS) processing.
*/
TssShareSignature = 98;
}

/**
Expand Down
16 changes: 12 additions & 4 deletions sdk/src/main/proto/block_stream_info.proto
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ message BlockStreamInfo {
* The latest available hash SHALL be for block N-1.<br/>
* This is REQUIRED to implement the EVM `BLOCKHASH` opcode.
* <p>
* <div style="display: block;font-size: .83em;margin-top: 1.67em;margin-bottom: 1.67em;margin-left: 0;margin-right: 0;font-weight: bold;">Field Length</div>
* ### Field Length
* Each hash value SHALL be the trailing 265 bits of a SHA2-384 hash.<br/>
* The length of this field SHALL be an integer multiple of 32 bytes.<br/>
* This field SHALL be at least 32 bytes.<br/>
Expand Down Expand Up @@ -143,9 +143,9 @@ message BlockStreamInfo {

/**
* A version describing the version of application software.
* <p>
* This SHALL be the software version that created this block.
*/
* <p>
* This SHALL be the software version that created this block.
*/
proto.SemanticVersion creation_software_version = 11;

/**
Expand All @@ -155,4 +155,12 @@ message BlockStreamInfo {
* at which an interval of time-dependent events were processed.
*/
proto.Timestamp last_interval_process_time = 12;

/**
* The time stamp at which the last user transaction was handled.
* <p>
* This field SHALL hold the consensus time for the last time
* at which a user transaction was handled.
*/
proto.Timestamp last_handle_time = 13;
}
2 changes: 1 addition & 1 deletion sdk/src/main/proto/ledger_id.proto
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ message LedgerId {
/**
* A signature from the prior ledger key.<br/>
* This signature is the _previous_ ledger ID signing _this_ ledger ID.<br/>
* This value MAY be unset, if there is no prior ledger ID.</br>
* This value MAY be unset, if there is no prior ledger ID.<br/>
* This value SHOULD be set if a prior ledger ID exists
* to generate the signature.
*/
Expand Down
5 changes: 2 additions & 3 deletions sdk/src/main/proto/node_delete.proto
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,8 @@ option java_multiple_files = true;
* - A deleted address book node SHALL be removed entirely from network state.
* - A deleted address book node identifier SHALL NOT be reused.
*
* ### Record Stream Effects
* Upon completion the "deleted" `node_id` SHALL be in the transaction
* receipt.
* ### Block Stream Effects
* None.
*/
message NodeDeleteTransactionBody {
/**
Expand Down
9 changes: 3 additions & 6 deletions sdk/src/main/proto/node_update.proto
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,8 @@ import "basic_types.proto";
* configuration during the next `freeze` transaction with the field
* `freeze_type` set to `PREPARE_UPGRADE`.
*
* ### Record Stream Effects
* Upon completion the `node_id` for the updated entry SHALL be in the
* transaction receipt.
* ### Block Stream Effects
* None.
*/
message NodeUpdateTransactionBody {
/**
Expand Down Expand Up @@ -91,9 +90,7 @@ message NodeUpdateTransactionBody {
* details.<br/>
* <blockquote>Example<blockquote>
* Hedera Mainnet _requires_ that address be specified, and does not
* permit DNS name (FQDN) to be specified.<br/>
* Mainnet also requires that the first entry be an "internal" IP
* address and the second entry be an "external" IP address.
* permit DNS name (FQDN) to be specified.
* </blockquote>
* <blockquote>
* Solo, however, _requires_ DNS name (FQDN) but also permits
Expand Down
92 changes: 63 additions & 29 deletions sdk/src/main/proto/recordcache.proto
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
/**
* # Record Cache
* The Record Cache holds transaction records for a short time, and is the
* source for responses to `transactionGetRecord` and `transactionGetReceipt`
* queries.
*
* ### Keywords
* The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
* "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
* document are to be interpreted as described in [RFC2119](https://www.ietf.org/rfc/rfc2119)
* and clarified in [RFC8174](https://www.ietf.org/rfc/rfc8174).
*/
syntax = "proto3";

package proto;

/*-
* ‌
* Hedera Network Services Protobuf
* ​
* Copyright (C) 2018 - 2023 Hedera Hashgraph, LLC
* ​
/*
* Copyright (C) 2023-2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
Expand All @@ -19,7 +28,6 @@ package proto;
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* ‍
*/

import "basic_types.proto";
Expand All @@ -31,57 +39,83 @@ option java_package = "com.hedera.hashgraph.sdk.proto";
option java_multiple_files = true;

/**
* As transactions are handled and records and receipts are created, they are stored in state for a configured time
* limit (perhaps, for example, 3 minutes). During this time window, any client can query the node and get the record
* or receipt for the transaction. The TransactionRecordEntry is the object stored in state with this information.
* As transactions are handled and records and receipts are created, they are
* stored in state for a configured time period (for example, 3 minutes).
* During this time, any client can query the node and get the record or receipt
* for the transaction. The `TransactionRecordEntry` is the object stored in
* state with this information.
*/
message TransactionRecordEntry {
/**
* The ID of the node that submitted the transaction to consensus. The ID is the ID of the node as known by the
* address book. Valid node IDs are in the range 0..2^63-1, inclusive.
* A node identifier.<br/>
* This identifier is the node, as known to the address book, that
* submitted the transaction for consensus.
* <p>
* This SHALL be a whole number.
*/
int64 node_id = 1;

/**
* The AccountID of the payer of the transaction. This may be the same as the account ID within the Transaction ID
* of the record, or it may be the account ID of the node that submitted the transaction to consensus if the account
* ID in the Transaction ID is not able to pay.
* An Account identifier for the payer for the transaction.
* <p>
* This MAY be the same as the account ID within the Transaction ID of the
* record, or it MAY be the account ID of the node that submitted the
* transaction to consensus if the account ID in the Transaction ID was
* not able to pay.
*/
AccountID payer_account_id = 2;

/**
* The transaction record for the transaction.
* A transaction record for the transaction.
*/
TransactionRecord transaction_record = 3;
}

/**
* As a single transaction is handled a receipt is created. It is stored in state for a configured time
* limit (perhaps, for example, 3 minutes). During this time window, any client can query the node and get the
* receipt for the transaction. The TransactionReceiptEntry is the object stored in state with this information.
* An entry in the record cache with the receipt for a transaction.
* This is the entry stored in state that enables returning the receipt
* information when queried by clients.
*
* When a transaction is handled a receipt SHALL be created.<br/>
* This receipt MUST be stored in state for a configured time limit
* (e.g. 3 minutes).<br/>
* While a receipt is stored, a client MAY query the node and retrieve
* the receipt.
*/
message TransactionReceiptEntry {
/**
* The ID of the node that submitted the transaction to consensus. The ID is the ID of the node as known by the
* address book. Valid node IDs are in the range 0..2^63-1, inclusive.
*/
* A node identifier.<br/>
* This identifies the node that submitted the transaction to consensus.
* The value is the identifier as known to the current address book.
* <p>
* Valid node identifiers SHALL be between 0 and <tt>2<sup>63-1</sup></tt>,
* inclusive.
*/
uint64 node_id = 1;

/**
* The id of the submitted transaction.
* A transaction identifier.<br/>
* This identifies the submitted transaction for this receipt.
*/
TransactionID transaction_id = 2;

/**
* The resulting status of handling the transaction.
* A status result.<br/>
* This is the final status after handling the transaction.
*/
ResponseCodeEnum status = 3;
}

/**
* As transactions are handled and receipts are created, they are stored in state for a configured time
* limit (perhaps, for example, 3 minutes). During this time window, any client can query the node and get the
* receipt for the transaction. The TransactionReceiptEntries is the object stored in state with this information.
* This object contains a list of TransactionReceiptEntry objects.
* A cache of transaction receipts.<br/>
* As transactions are handled and receipts are created, they are stored in
* state for a configured time limit (perhaps, for example, 3 minutes).
* During this time window, any client can query the node and get the receipt
* for the transaction. The `TransactionReceiptEntries` is the object stored in
* state with this information.
*
* This message SHALL contain a list of `TransactionReceiptEntry` objects.
*/
message TransactionReceiptEntries {
repeated TransactionReceiptEntry entries = 1;
}
}
32 changes: 32 additions & 0 deletions sdk/src/main/proto/response_code.proto
Original file line number Diff line number Diff line change
Expand Up @@ -1593,4 +1593,36 @@ enum ResponseCodeEnum {
* airdrop and whether the sender can fulfill the offer.
*/
INVALID_TOKEN_IN_PENDING_AIRDROP = 369;

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time not strictly after the time at which its creation reached
* consensus.
*/
SCHEDULE_EXPIRY_MUST_BE_FUTURE = 370;

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time too far in the future after the time at which its creation
* reached consensus.
*/
SCHEDULE_EXPIRY_TOO_LONG = 371;

/**
* A scheduled transaction configured to wait for expiry to execute was given
* an expiry time at which there is already too many transactions scheduled to
* expire; its creation must be retried with a different expiry.
*/
SCHEDULE_EXPIRY_IS_BUSY = 372;

/**
* The provided gRPC certificate hash is invalid.
*/
INVALID_GRPC_CERTIFICATE_HASH = 373;

/**
* A scheduled transaction configured to wait for expiry to execute was not
* given an explicit expiration time.
*/
MISSING_EXPIRY_TIME = 374;
}
Loading