diff --git a/hapi/hedera-protobufs/services/tss_message.proto b/hapi/hedera-protobufs/services/auxiliary/tss/tss_message.proto similarity index 52% rename from hapi/hedera-protobufs/services/tss_message.proto rename to hapi/hedera-protobufs/services/auxiliary/tss/tss_message.proto index 2af5e1ed49c1..921652ba12cb 100644 --- a/hapi/hedera-protobufs/services/tss_message.proto +++ b/hapi/hedera-protobufs/services/auxiliary/tss/tss_message.proto @@ -10,7 +10,7 @@ */ syntax = "proto3"; -package proto; +package com.hedera.hapi.services.auxiliary.tss; /* * Copyright (C) 2024 Hedera Hashgraph, LLC @@ -28,23 +28,29 @@ package proto; * limitations under the License. */ -option java_package = "com.hederahashgraph.api.proto.java"; -// <<>> This comment is special code for setting PBJ Compiler java package +option java_package = "com.hedera.hapi.services.auxiliary.tss.legacy"; +// <<>> This comment is special code for setting PBJ Compiler java package option java_multiple_files = true; -/** The TssMessageTransaction is used to send a TssMessage to the network for a - * candidate roster. - *
- * This transaction contains the information to identify the source and target - * rosters, as well as the specific TssMessage being sent. - */ +/** A transaction body to to send a Threshold Signature Scheme (TSS) + * Message.
+ * This is a wrapper around several different TSS message types that a node + * might communicate with other nodes in the network. + * + * - A `TssMessageTransactionBody` MUST identify the hash of the roster + * containing the node generating this TssMessage + * - A `TssMessageTransactionBody` MUST identify the hash of the roster that + * the TSS messages is for + * - A `TssMessageTransactionBody` SHALL contain the specificc TssMessage data + * that has been generated by the node for the share_index. + */ message TssMessageTransactionBody { /** - * A hash of the roster containing the node generating the TssMessage. - *
- * This hash uniquely identifies the source roster. + * A hash of the roster containing the node generating the TssMessage.
+ * This hash uniquely identifies the source roster, which will include + * an entry for the node generating this TssMessage. *

* This value MUST be set.
* This value MUST NOT be empty.
@@ -62,17 +68,21 @@ message TssMessageTransactionBody { bytes target_roster_hash = 2; /** - * An index to order shares.
- * This establishes a global ordering of shares across all shares in - * the network.
- * It corresponds to the index of the public share in the list returned from - * the TSS library when the share was created for the source roster. + * An index to order shares. + *

+ * A share index SHALL establish a global ordering of shares across all + * shares in the network.
+ * A share index MUST correspond to the index of the public share in the list + * returned from the TSS library when the share was created for the source + * roster. */ uint64 share_index = 3; /** - * A byte array containing the TssMessage data generated by the node for the - * share_index. + * A byte array. + *

+ * This field SHALL contain the TssMessage data generated by the node + * for the specified `share_index`. */ bytes tss_message = 4; } diff --git a/hapi/hedera-protobufs/services/auxiliary/tss/tss_vote.proto b/hapi/hedera-protobufs/services/auxiliary/tss/tss_vote.proto new file mode 100644 index 000000000000..97eb559a43b2 --- /dev/null +++ b/hapi/hedera-protobufs/services/auxiliary/tss/tss_vote.proto @@ -0,0 +1,98 @@ +/** + * # Tss Vote Transaction + * + * ### 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 com.hedera.hapi.services.auxiliary.tss; + +/* + * Copyright (C) 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 + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * 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. + */ + +option java_package = "com.hedera.hapi.services.auxiliary.tss.legacy"; +// <<>> This comment is special code for setting PBJ Compiler java package +option java_multiple_files = true; + +/** + * A transaction body to vote on the validity of Threshold Signature Scheme + * (TSS) Messages for a candidate roster. + * + * - A `TssVoteTransactionBody` MUST identify the hash of the roster containing + * the node generating this TssVote + * - A `TssVoteTransactionBody` MUST identify the hash of the roster that the + * TSS messages is for + * - If the candidate roster has received enough yes votes, the candidate + * roster SHALL be adopted. + * - Switching to the candidate roster MUST not happen until enough nodes have + * voted that they have verified a threshold number of TSS messages from the + * active roster. + * - A vote consists of a bit vector of message statuses where each bit + * corresponds to the order of TssMessages as they have come through + * consensus. + * - The threshold for votes to adopt a candidate roster SHALL be at least 1/3 + * of the consensus weight of the active roster to ensure that at least 1 + * honest node has validated the TSS key material. + */ +message TssVoteTransactionBody { + + /** + * A hash of the roster containing the node generating this TssVote. + */ + bytes source_roster_hash = 1; + + /** + * A hash of the roster that this TssVote is for. + */ + bytes target_roster_hash = 2; + + /** + * An identifier (and public key) computed from the TssMessages for the target + * roster. + */ + bytes ledger_id = 3; + + /** + * A signature produced by the node. + *

+ * This signature SHALL be produced using the node RSA signing key to sign + * the ledger_id.
+ * This signature SHALL be used to establish a chain of trust in the ledger id. + */ + bytes node_signature = 4; + + /** + * A bit vector of message statuses. + *

+ * #### Example + *

+ * A bit SHALL be set if the `TssMessage` for the `TssMessageTransaction` + * with a sequence number matching that bit index has been + * received, and is valid.
+ * A bit SHALL NOT be set if the `TssMessage` has not been received or was + * received but not valid. + */ + bytes tss_vote = 5; +} diff --git a/hapi/hedera-protobufs/services/state/roster/ledger_id.proto b/hapi/hedera-protobufs/services/state/roster/ledger_id.proto index 7b4564359fd8..fe96db96e396 100644 --- a/hapi/hedera-protobufs/services/state/roster/ledger_id.proto +++ b/hapi/hedera-protobufs/services/state/roster/ledger_id.proto @@ -39,19 +39,21 @@ option java_multiple_files = true; /** * A ledger identifier.
- * This message identifies a ledger and can be used to verify ledger signatures. - * A LedgerId may change, but does so only in rare circumstances. + * This message identifies a ledger and is used to verify ledger + * signatures in a Threshold Signature Scheme (TSS). * * A ledger identifier SHALL be a public key defined according to the TSS * process.
- * A ledger identifier SHOULD NOT change, but MAY do so in rare circumstances. - * Clients SHOULD always check for the correct ledger identifier, according to the - * network roster, before attempting to verify any state proof or other ledger - * signature. + * A ledger identifier SHOULD NOT change, but MAY do so in rare + * circumstances.
+ * Clients SHOULD always check for the correct ledger identifier, according to + * the network roster, before attempting to verify any state proof or other + * ledger signature. * * ### Block Stream Effects - * Every Block Stream `BlockProof` item SHALL be signed via TSS and MUST be - * verified with the ledger identifier current at the _start_ of that block. + * Every block in the Block Stream `BlockProof` SHALL be signed via TSS and + * MUST be verified with the ledger identifier current at the _start_ of that + * block. * If the ledger identifier changes, the new value MUST be used to validate * Block Proof items after the change. * A change to the ledger identifier SHALL be reported in a State Change for @@ -62,7 +64,8 @@ message LedgerId { /** * A public key.
- * This key both identifies the ledger and can be used to verify ledger signatures. + * This key both identifies the ledger and can be used to verify ledger + * signatures. *

* This value MUST be set.
* This value MUST NOT be empty.
@@ -72,25 +75,25 @@ message LedgerId { /** * A round number.
- * This identifies when this ledger id becomes active. - *

+ * This identifies when this ledger id becomes active.
* This value is REQUIRED. */ uint64 round = 2; /** * A signature from the prior ledger key.
- * This signature is the _previous_ ledger ID signing _this_ ledger ID. - *

- * This value MAY be unset, if there is no prior ledger ID.
+ * This signature is the _previous_ ledger ID signing _this_ ledger ID.
+ * This value MAY be unset, if there is no prior ledger ID.
* This value SHOULD be set if a prior ledger ID exists * to generate the signature. */ bytes ledger_signature = 3; /** - * The signatures from nodes in the active roster signing the new ledger id.
- * These signatures establish a chain of trust from the network to the new ledger id. + * The signatures from nodes in the active roster signing the new + * ledger id.
+ * These signatures establish a chain of trust from the network to the new + * ledger id. *

* This value MUST be present when the ledger signature of a previous ledger * id is absent. @@ -121,11 +124,17 @@ message RosterSignatures { message NodeSignature { /** * The node id of the node that created the _RSA_ signature. + * This value MUST be set.
+ * This value MUST NOT be empty.
+ * This value is REQUIRED. */ uint64 node_id = 1; /** * The bytes of an _RSA_ signature. + * This value MUST be set.
+ * This value MUST NOT be empty.
+ * This value MUST contain a valid signature. */ bytes node_signature = 2; } diff --git a/hapi/hedera-protobufs/services/state/tss/tss_message_map_key.proto b/hapi/hedera-protobufs/services/state/tss/tss_message_map_key.proto index 4996b3ba39a0..bd33431563d8 100644 --- a/hapi/hedera-protobufs/services/state/tss/tss_message_map_key.proto +++ b/hapi/hedera-protobufs/services/state/tss/tss_message_map_key.proto @@ -13,8 +13,6 @@ syntax = "proto3"; package com.hedera.hapi.node.state.tss; /* - * Hedera Network Services Protobuf - * * Copyright (C) 2024 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,14 +28,15 @@ package com.hedera.hapi.node.state.tss; * limitations under the License. */ -option java_package = "com.hederahashgraph.api.proto.java"; +option java_package = "com.hedera.hapi.node.state.tss.legacy"; // <<>> This comment is special code for setting PBJ Compiler java package option java_multiple_files = true; /** - * A key for use in the TssMessageMaps.
- * This key is used to uniquely identify entries in the TssMessageMaps. - */ + * A key for use in the Threshold Signature Scheme (TSS) TssMessageMaps. + * + * This key SHALL be used to uniquely identify entries in the Message Maps. + */ message TssMessageMapKey { /** diff --git a/hapi/hedera-protobufs/services/state/tss/tss_vote_map_key.proto b/hapi/hedera-protobufs/services/state/tss/tss_vote_map_key.proto index c7100dc64839..6ea669c73d99 100644 --- a/hapi/hedera-protobufs/services/state/tss/tss_vote_map_key.proto +++ b/hapi/hedera-protobufs/services/state/tss/tss_vote_map_key.proto @@ -13,8 +13,6 @@ syntax = "proto3"; package com.hedera.hapi.node.state.tss; /* - * Hedera Network Services Protobuf - * * Copyright (C) 2024 Hedera Hashgraph, LLC * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,13 +28,14 @@ package com.hedera.hapi.node.state.tss; * limitations under the License. */ -option java_package = "com.hederahashgraph.api.proto.java"; +option java_package = "com.hedera.hapi.node.state.tss.legacy"; // <<>> This comment is special code for setting PBJ Compiler java package option java_multiple_files = true; /** - * A key for use in the TssVoteMaps.
- * This key is used to uniquely identify entries in the TssVoteMaps. + * A key for use in the Threshold Signature Scheme (TSS) TssVoteMaps. + * + * This key SHALL be used to uniquely identify entries in the Vote Maps. */ message TssVoteMapKey { @@ -49,8 +48,7 @@ message TssVoteMapKey { */ bytes roster_hash = 1; - /* The node id of the node that created the TssVote. - *
+ /** The node id of the node that created the TssVote.
* This id uniquely identifies the node. *

* This value MUST be set.
diff --git a/hapi/hedera-protobufs/services/transaction_body.proto b/hapi/hedera-protobufs/services/transaction_body.proto index 4746467407e7..75557d43e6b7 100644 --- a/hapi/hedera-protobufs/services/transaction_body.proto +++ b/hapi/hedera-protobufs/services/transaction_body.proto @@ -89,8 +89,8 @@ import "node_create.proto"; import "node_update.proto"; import "node_delete.proto"; -import "tss_message.proto"; -import "tss_vote.proto"; +import "auxiliary/tss/tss_message.proto"; +import "auxiliary/tss/tss_vote.proto"; /** * A single transaction. All transaction types are possible here. @@ -425,11 +425,11 @@ message TransactionBody { /** * A transaction body for a `tssMessage` request. */ - TssMessageTransactionBody tssMessage = 61; + com.hedera.hapi.services.auxiliary.tss.TssMessageTransactionBody tssMessage = 61; /** * A transaction body for a `tssVote` request. */ - TssVoteTransactionBody tssVote = 62; + com.hedera.hapi.services.auxiliary.tss.TssVoteTransactionBody tssVote = 62; } } diff --git a/hapi/hedera-protobufs/services/tss_vote.proto b/hapi/hedera-protobufs/services/tss_vote.proto deleted file mode 100644 index 30134c5c2f1e..000000000000 --- a/hapi/hedera-protobufs/services/tss_vote.proto +++ /dev/null @@ -1,80 +0,0 @@ -/** - * # Tss Vote Transaction - * - * ### 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; - -/* - * Copyright (C) 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 - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * 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. - */ - -option java_package = "com.hederahashgraph.api.proto.java"; -// <<>> This comment is special code for setting PBJ Compiler java package -option java_multiple_files = true; - -/** - * A transaction used to vote on the validity of TssMessages for a candidate roster. - */ -message TssVoteTransactionBody { - - /** - * A hash of the roster containing the node generating this TssVote. - */ - bytes source_roster_hash = 1; - - /** - * A hash of the roster that this TssVote is for. - */ - bytes target_roster_hash = 2; - - /** - * An identifier (and public key) computed from the TssMessages for the target roster. - */ - bytes ledger_id = 3; - - /** - * A signature produced by the node.
- * This is produced using the node RSA signing key to sign the ledger_id.
- * This signature is used to establish a chain of trust in the ledger id. - */ - bytes node_signature = 4; - - /** - * A bit vector of message statuses.
- * Each bit in this vector indicates receipt (1) or non-receipt (0) of a - * _valid_ `TssMessage` for a corresponding `TssMessageTransaction`. - *

- * #### Example
- *

- * A bit SHALL be set if the `TssMessage` for the `TssMessageTransaction` - * with a sequence number matching that bit index has been - * received, and is valid.
- * A bit SHALL NOT be set if the `TssMessage` has not been received or was - * received but not valid. - */ - bytes tss_vote = 5; -} diff --git a/hapi/src/main/java/module-info.java b/hapi/src/main/java/module-info.java index 2137b5b8c832..676ba5935f50 100644 --- a/hapi/src/main/java/module-info.java +++ b/hapi/src/main/java/module-info.java @@ -23,9 +23,6 @@ exports com.hedera.hapi.node.token; exports com.hedera.hapi.node.token.codec; exports com.hedera.hapi.node.token.schema; - exports com.hedera.hapi.node.tss; - exports com.hedera.hapi.node.tss.codec; - exports com.hedera.hapi.node.tss.schema; exports com.hedera.hapi.node.transaction; exports com.hedera.hapi.node.transaction.codec; exports com.hedera.hapi.node.transaction.schema; @@ -66,6 +63,7 @@ exports com.hedera.hapi.node.state.roster; exports com.hedera.hapi.block.stream.schema; exports com.hedera.hapi.node.state.tss; + exports com.hedera.hapi.services.auxiliary.tss; requires transitive com.google.common; requires transitive com.google.protobuf; diff --git a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/tss/schemas/V0560TSSSchema.java b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/tss/schemas/V0560TSSSchema.java index 2df3da4745e2..c59302d6ba91 100644 --- a/hedera-node/hedera-app/src/main/java/com/hedera/node/app/tss/schemas/V0560TSSSchema.java +++ b/hedera-node/hedera-app/src/main/java/com/hedera/node/app/tss/schemas/V0560TSSSchema.java @@ -19,8 +19,8 @@ import com.hedera.hapi.node.base.SemanticVersion; import com.hedera.hapi.node.state.tss.TssMessageMapKey; import com.hedera.hapi.node.state.tss.TssVoteMapKey; -import com.hedera.hapi.node.tss.TssMessageTransactionBody; -import com.hedera.hapi.node.tss.TssVoteTransactionBody; +import com.hedera.hapi.services.auxiliary.tss.TssMessageTransactionBody; +import com.hedera.hapi.services.auxiliary.tss.TssVoteTransactionBody; import com.swirlds.state.spi.Schema; import com.swirlds.state.spi.StateDefinition; import edu.umd.cs.findbugs.annotations.NonNull;