All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hedera.hashgraph.sdk.NodeCreateTransaction Maven / Gradle / Ivy

There is a newer version: 2.40.0
Show newest version
/*-
 *
 * Hedera Java SDK
 *
 * 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.
 *
 */
package com.hedera.hashgraph.sdk;

import com.google.protobuf.ByteString;
import com.google.protobuf.InvalidProtocolBufferException;
import com.hedera.hashgraph.sdk.proto.AddressBookServiceGrpc;
import com.hedera.hashgraph.sdk.proto.NodeCreateTransactionBody;
import com.hedera.hashgraph.sdk.proto.SchedulableTransactionBody;
import com.hedera.hashgraph.sdk.proto.TransactionBody;
import com.hedera.hashgraph.sdk.proto.TransactionResponse;
import io.grpc.MethodDescriptor;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Objects;
import javax.annotation.Nullable;
import org.bouncycastle.util.Arrays;

/**
 * A transaction to create a new node in the network address book.
 * The transaction, once complete, enables a new consensus node
 * to join the network, and requires governing council authorization.
 * 

* This transaction body SHALL be considered a "privileged transaction". *

* * - MUST be signed by the governing council. * - MUST be signed by the `Key` assigned to the * `admin_key` field. * - The newly created node information SHALL be added to the network address * book information in the network state. * - The new entry SHALL be created in "state" but SHALL NOT participate in * network consensus and SHALL NOT be present in network "configuration" * until the next "upgrade" transaction (as noted below). * - All new address book entries SHALL be added to the active network * configuration during the next `freeze` transaction with the field * `freeze_type` set to `PREPARE_UPGRADE`. * * ### Record Stream Effects * Upon completion the newly assigned `node_id` SHALL be in the transaction * receipt. */ public class NodeCreateTransaction extends Transaction { /** * A Node account identifier. *

* This account identifier MUST be in the "account number" form.
* This account identifier MUST NOT use the alias field.
* If the identified account does not exist, this transaction SHALL fail.
* Multiple nodes MAY share the same node account.
* This field is REQUIRED. */ @Nullable private AccountId accountId = null; /** * A short description of the node. *

* This value, if set, MUST NOT exceed 100 bytes when encoded as UTF-8.
* This field is OPTIONAL. */ private String description = ""; /** * A list of service endpoints for gossip. *

* These endpoints SHALL represent the published endpoints to which other * consensus nodes may _gossip_ transactions.
* These endpoints MUST specify a port.
* This list MUST NOT be empty.
* This list MUST NOT contain more than `10` entries.
* The first two entries in this list SHALL be the endpoints published to * all consensus nodes.
* All other entries SHALL be reserved for future use. *

* Each network may have additional requirements for these endpoints. * A client MUST check network-specific documentation for those * details.
* If the network configuration value `gossipFqdnRestricted` is set, then * all endpoints in this list MUST supply only IP address.
* If the network configuration value `gossipFqdnRestricted` is _not_ set, * then endpoints in this list MAY supply either IP address or FQDN, but * MUST NOT supply both values for the same endpoint. */ private List gossipEndpoints = new ArrayList<>(); /** * A list of service endpoints for gRPC calls. *

* These endpoints SHALL represent the published gRPC endpoints to which * clients may submit transactions.
* These endpoints MUST specify a port.
* Endpoints in this list MAY supply either IP address or FQDN, but MUST * NOT supply both values for the same endpoint.
* This list MUST NOT be empty.
* This list MUST NOT contain more than `8` entries. */ private List serviceEndpoints = new ArrayList<>(); /** * A certificate used to sign gossip events. *

* This value MUST be a certificate of a type permitted for gossip * signatures.
* This value MUST be the DER encoding of the certificate presented.
* This field is REQUIRED and MUST NOT be empty. */ @Nullable private byte[] gossipCaCertificate = null; /** * A hash of the node gRPC TLS certificate. *

* This value MAY be used to verify the certificate presented by the node * during TLS negotiation for gRPC.
* This value MUST be a SHA-384 hash.
* The TLS certificate to be hashed MUST first be in PEM format and MUST be * encoded with UTF-8 NFKD encoding to a stream of bytes provided to * the hash algorithm.
* This field is OPTIONAL. */ @Nullable private byte[] grpcCertificateHash = null; /** * An administrative key controlled by the node operator. *

* This key MUST sign this transaction.
* This key MUST sign each transaction to update this node.
* This field MUST contain a valid `Key` value.
* This field is REQUIRED and MUST NOT be set to an empty `KeyList`. */ @Nullable private Key adminKey = null; /** * Constructor. */ public NodeCreateTransaction() {} /** * Constructor. * * @param txs Compound list of transaction id's list of (AccountId, Transaction) records * @throws InvalidProtocolBufferException when there is an issue with the protobuf */ NodeCreateTransaction( LinkedHashMap> txs) throws InvalidProtocolBufferException { super(txs); initFromTransactionBody(); } /** * Constructor. * * @param txBody protobuf TransactionBody */ NodeCreateTransaction(com.hedera.hashgraph.sdk.proto.TransactionBody txBody) { super(txBody); initFromTransactionBody(); } /** * Extract the Account ID of the Node. * @return the Account ID of the Node. */ public AccountId getAccountId() { return accountId; } /** * Assign the Account ID of the Node. * @param accountId the Account ID of the Node. * @return {@code this} */ public NodeCreateTransaction setAccountId(AccountId accountId) { Objects.requireNonNull(accountId); requireNotFrozen(); this.accountId = accountId; return this; } /** * Extract the description of the node. * @return the node's description. */ public String getDescription() { return description; } /** * Sets the description of the node. * @param description The String to be set as the description of the node. * @return {@code this} */ public NodeCreateTransaction setDescription(String description) { requireNotFrozen(); Objects.requireNonNull(description); this.description = description; return this; } /** * Extract the list of service endpoints for gossip. * @return the list of service endpoints for gossip. */ public List getGossipEndpoints() { return gossipEndpoints; } /** * Assign the list of service endpoints for gossip. * @param gossipEndpoints the list of service endpoints for gossip. * @return {@code this} */ public NodeCreateTransaction setGossipEndpoints(List gossipEndpoints) { requireNotFrozen(); Objects.requireNonNull(gossipEndpoints); this.gossipEndpoints = new ArrayList<>(gossipEndpoints); return this; } /** * Add an endpoint for gossip to the list of service endpoints for gossip. * @param gossipEndpoint endpoints for gossip to add. * @return {@code this} */ public NodeCreateTransaction addGossipEndpoint(Endpoint gossipEndpoint) { requireNotFrozen(); gossipEndpoints.add(gossipEndpoint); return this; } /** * Extract the list of service endpoints for gRPC calls. * @return the list of service endpoints for gRPC calls. */ public List getServiceEndpoints() { return serviceEndpoints; } /** * Assign the list of service endpoints for gRPC calls. * @param serviceEndpoints list of service endpoints for gRPC calls. * @return {@code this} */ public NodeCreateTransaction setServiceEndpoints(List serviceEndpoints) { requireNotFrozen(); Objects.requireNonNull(serviceEndpoints); this.serviceEndpoints = new ArrayList<>(serviceEndpoints); return this; } /** * Add an endpoint for gRPC calls to the list of service endpoints for gRPC calls. * @param serviceEndpoint endpoints for gRPC calls to add. * @return {@code this} */ public NodeCreateTransaction addServiceEndpoint(Endpoint serviceEndpoint) { requireNotFrozen(); serviceEndpoints.add(serviceEndpoint); return this; } /** * Extract the certificate used to sign gossip events. * @return the DER encoding of the certificate presented. */ @Nullable public byte[] getGossipCaCertificate() { return gossipCaCertificate != null ? Arrays.copyOf(gossipCaCertificate, gossipCaCertificate.length) : null; } /** * Sets the certificate used to sign gossip events. *
* This value MUST be the DER encoding of the certificate presented. * @param gossipCaCertificate the DER encoding of the certificate presented. * @return {@code this} */ public NodeCreateTransaction setGossipCaCertificate(byte[] gossipCaCertificate) { Objects.requireNonNull(gossipCaCertificate); requireNotFrozen(); this.gossipCaCertificate = Arrays.copyOf(gossipCaCertificate, gossipCaCertificate.length); return this; } /** * Extract the hash of the node gRPC TLS certificate. * @return SHA-384 hash of the node gRPC TLS certificate. */ @Nullable public byte[] getGrpcCertificateHash() { return grpcCertificateHash != null ? Arrays.copyOf(grpcCertificateHash, grpcCertificateHash.length) : null; } /** * Sets the hash of the node gRPC TLS certificate. *
* This value MUST be a SHA-384 hash. * @param grpcCertificateHash SHA-384 hash of the node gRPC TLS certificate. * @return {@code this} */ public NodeCreateTransaction setGrpcCertificateHash(byte[] grpcCertificateHash) { Objects.requireNonNull(grpcCertificateHash); requireNotFrozen(); this.grpcCertificateHash = Arrays.copyOf(grpcCertificateHash, grpcCertificateHash.length); return this; } /** * Get an administrative key controlled by the node operator. * @return an administrative key controlled by the node operator. */ @Nullable public Key getAdminKey() { return adminKey; } /** * Sets an administrative key controlled by the node operator. * @param adminKey an administrative key to be set. * @return {@code this} */ public NodeCreateTransaction setAdminKey(Key adminKey) { Objects.requireNonNull(adminKey); requireNotFrozen(); this.adminKey = adminKey; return this; } /** * Build the transaction body. * * @return {@link com.hedera.hashgraph.sdk.proto.NodeCreateTransactionBody} */ NodeCreateTransactionBody.Builder build() { var builder = NodeCreateTransactionBody.newBuilder(); if (accountId != null) { builder.setAccountId(accountId.toProtobuf()); } builder.setDescription(description); for (Endpoint gossipEndpoint : gossipEndpoints) { builder.addGossipEndpoint(gossipEndpoint.toProtobuf()); } for (Endpoint serviceEndpoint : serviceEndpoints) { builder.addServiceEndpoint(serviceEndpoint.toProtobuf()); } if (gossipCaCertificate != null) { builder.setGossipCaCertificate(ByteString.copyFrom(gossipCaCertificate)); } if (grpcCertificateHash != null) { builder.setGrpcCertificateHash(ByteString.copyFrom(grpcCertificateHash)); } if (adminKey != null) { builder.setAdminKey(adminKey.toProtobufKey()); } return builder; } /** * Initialize from the transaction body. */ void initFromTransactionBody() { var body = sourceTransactionBody.getNodeCreate(); if (body.hasAccountId()) { accountId = AccountId.fromProtobuf(body.getAccountId()); } description = body.getDescription(); for (var gossipEndpoint : body.getGossipEndpointList()) { gossipEndpoints.add(Endpoint.fromProtobuf(gossipEndpoint)); } for (var serviceEndpoint : body.getServiceEndpointList()) { serviceEndpoints.add(Endpoint.fromProtobuf(serviceEndpoint)); } gossipCaCertificate = body.getGossipCaCertificate().toByteArray(); grpcCertificateHash = body.getGrpcCertificateHash().toByteArray(); if (body.hasAdminKey()) { adminKey = Key.fromProtobufKey(body.getAdminKey()); } } @Override void validateChecksums(Client client) throws BadEntityIdException { if (accountId != null) { accountId.validateChecksum(client); } } @Override MethodDescriptor getMethodDescriptor() { return AddressBookServiceGrpc.getCreateNodeMethod(); } @Override void onFreeze(TransactionBody.Builder bodyBuilder) { bodyBuilder.setNodeCreate(build()); } @Override void onScheduled(SchedulableTransactionBody.Builder scheduled) { scheduled.setNodeCreate(build()); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy