Skip to content

Commit

Permalink
Add TokenFreezeTransaction unit tests and integration tests
Browse files Browse the repository at this point in the history
Signed-off-by: Rob Walworth <robert.walworth@swirldslabs.com>
  • Loading branch information
rwalworth committed Jul 7, 2023
1 parent b05cbc7 commit 885a971
Show file tree
Hide file tree
Showing 12 changed files with 677 additions and 2 deletions.
1 change: 1 addition & 0 deletions sdk/main/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ add_library(${PROJECT_NAME} STATIC
src/TokenDeleteTransaction.cc
src/TokenDissociateTransaction.cc
src/TokenFeeScheduleUpdateTransaction.cc
src/TokenFreezeTransaction.cc
src/TokenId.cc
src/TokenInfo.cc
src/TokenInfoQuery.cc
Expand Down
146 changes: 146 additions & 0 deletions sdk/main/include/TokenFreezeTransaction.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/*-
*
* Hedera C++ SDK
*
* Copyright (C) 2020 - 2022 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.
*
*/
#ifndef HEDERA_SDK_CPP_TOKEN_FREEZE_TRANSACTION_H_
#define HEDERA_SDK_CPP_TOKEN_FREEZE_TRANSACTION_H_

#include "AccountId.h"
#include "TokenId.h"
#include "Transaction.h"

namespace proto
{
class TokenFreezeAccountTransactionBody;
class TransactionBody;
}

namespace Hedera
{
/**
* Freezes transfers of the specified token for the account. The transaction must be signed by the token's freeze key.
*
* - If the provided account is not found, the transaction will resolve to INVALID_ACCOUNT_ID.
* - If the provided account has been deleted, the transaction will resolve to ACCOUNT_DELETED.
* - If the provided token is not found, the transaction will resolve to INVALID_TOKEN_ID.
* - If the provided token has been deleted, the transaction will resolve to TOKEN_WAS_DELETED.
* - If an Association between the provided token and account is not found, the transaction will resolve to
* TOKEN_NOT_ASSOCIATED_TO_ACCOUNT.
* - If no Freeze Key is defined, the transaction will resolve to TOKEN_HAS_NO_FREEZE_KEY.
*
* Once executed the Account is marked as Frozen and will not be able to receive or send tokens unless unfrozen. The
* operation is idempotent.
*
* Transaction Signing Requirements:
* - Freeze key.
* - Transaction fee payer account key.
*/
class TokenFreezeTransaction : public Transaction<TokenFreezeTransaction>
{
public:
TokenFreezeTransaction() = default;

/**
* Construct from a TransactionBody protobuf object.
*
* @param transactionBody The TransactionBody protobuf object from which to construct.
* @throws std::invalid_argument If the input TransactionBody does not represent a TokenFreeze transaction.
*/
explicit TokenFreezeTransaction(const proto::TransactionBody& transactionBody);

/**
* Set the ID of the account to be frozen for the specified token.
*
* @param accountId The ID of the account to be frozen for the specified token.
* @return A reference to this TokenFreezeTransaction object with the newly-set account ID.
* @throws IllegalStateException If this TokenFreezeTransaction is frozen.
*/
TokenFreezeTransaction& setAccountId(const AccountId& accountId);

/**
* Set the ID of the token to be frozen for the specified account.
*
* @param tokenId The ID of the token to be frozen for the specified account.
* @return A reference to this TokenFreezeTransaction object with the newly-set token ID.
* @throws IllegalStateException If this TokenFreezeTransaction is frozen.
*/
TokenFreezeTransaction& setTokenId(const TokenId& tokenId);

/**
* Get the ID of the account to be frozen for the specified token.
*
* @return The ID of the account to be frozen for the specified token.
*/
[[nodiscard]] inline AccountId getAccountId() const { return mAccountId; }

/**
* Get the ID of the token to be frozen for the specified account.
*
* @return The ID of the token to be frozen for the specified account.
*/
[[nodiscard]] inline TokenId getTokenId() const { return mTokenId; }

private:
/**
* Derived from Executable. Construct a Transaction protobuf object from this TokenFreezeTransaction object.
*
* @param client The Client trying to construct this TokenFreezeTransaction.
* @param node The Node to which this TokenFreezeTransaction will be sent. This is unused.
* @return A Transaction protobuf object filled with this TokenFreezeTransaction object's data.
* @throws UninitializedException If the input client has no operator with which to sign this TokenFreezeTransaction.
*/
[[nodiscard]] proto::Transaction makeRequest(const Client& client,
const std::shared_ptr<internal::Node>& /*node*/) const override;

/**
* Derived from Executable. Submit this TokenFreezeTransaction to a Node.
*
* @param client The Client submitting this TokenFreezeTransaction.
* @param deadline The deadline for submitting this TokenFreezeTransaction.
* @param node Pointer to the Node to which this TokenFreezeTransaction should be submitted.
* @param response Pointer to the TransactionResponse protobuf object that gRPC should populate with the response
* information from the gRPC server.
* @return The gRPC status of the submission.
*/
[[nodiscard]] grpc::Status submitRequest(const Client& client,
const std::chrono::system_clock::time_point& deadline,
const std::shared_ptr<internal::Node>& node,
proto::TransactionResponse* response) const override;

/**
* Build a TokenFreezeAccountTransactionBody protobuf object from this TokenFreezeTransaction object.
*
* @return A pointer to a TokenFreezeAccountTransactionBody protobuf object filled with this TokenFreezeTransaction
* object's data.
*/
[[nodiscard]] proto::TokenFreezeAccountTransactionBody* build() const;

/**
* The ID of the account to be frozen for the specified token.
*/
AccountId mAccountId;

/**
* The ID of the token to be frozen for the specified account.
*/
TokenId mTokenId;
};

} // namespace Hedera

#endif // HEDERA_SDK_CPP_TOKEN_FREEZE_TRANSACTION_H_
4 changes: 3 additions & 1 deletion sdk/main/include/Transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ class TokenCreateTransaction;
class TokenDeleteTransaction;
class TokenDissociateTransaction;
class TokenFeeScheduleUpdateTransaction;
class TokenFreezeTransaction;
class TokenMintTransaction;
class TokenUpdateTransaction;
class TokenWipeTransaction;
Expand Down Expand Up @@ -138,7 +139,8 @@ class Transaction
TokenWipeTransaction,
TokenBurnTransaction,
TokenDissociateTransaction,
TokenFeeScheduleUpdateTransaction>>
TokenFeeScheduleUpdateTransaction,
TokenFreezeTransaction>>
fromBytes(const std::vector<std::byte>& bytes);

/**
Expand Down
2 changes: 2 additions & 0 deletions sdk/main/src/Executable.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#include "TokenDeleteTransaction.h"
#include "TokenDissociateTransaction.h"
#include "TokenFeeScheduleUpdateTransaction.h"
#include "TokenFreezeTransaction.h"
#include "TokenInfo.h"
#include "TokenInfoQuery.h"
#include "TokenMintTransaction.h"
Expand Down Expand Up @@ -371,6 +372,7 @@ template class Executable<TokenFeeScheduleUpdateTransaction,
proto::Transaction,
proto::TransactionResponse,
TransactionResponse>;
template class Executable<TokenFreezeTransaction, proto::Transaction, proto::TransactionResponse, TransactionResponse>;
template class Executable<TokenInfoQuery, proto::Query, proto::Response, TokenInfo>;
template class Executable<TokenMintTransaction, proto::Transaction, proto::TransactionResponse, TransactionResponse>;
template class Executable<TokenUpdateTransaction, proto::Transaction, proto::TransactionResponse, TransactionResponse>;
Expand Down
106 changes: 106 additions & 0 deletions sdk/main/src/TokenFreezeTransaction.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
/*-
*
* Hedera C++ SDK
*
* Copyright (C) 2020 - 2022 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.
*
*/
#include "TokenFreezeTransaction.h"
#include "impl/Node.h"

#include <grpcpp/client_context.h>
#include <proto/token_freeze_account.pb.h>
#include <proto/transaction.pb.h>
#include <stdexcept>

namespace Hedera
{
//-----
TokenFreezeTransaction::TokenFreezeTransaction(const proto::TransactionBody& transactionBody)
: Transaction<TokenFreezeTransaction>(transactionBody)
{
if (!transactionBody.has_tokenfreeze())
{
throw std::invalid_argument("Transaction body doesn't contain TokenFreeze data");
}

const proto::TokenFreezeAccountTransactionBody& body = transactionBody.tokenfreeze();

if (body.has_account())
{
mAccountId = AccountId::fromProtobuf(body.account());
}

if (body.has_token())
{
mTokenId = TokenId::fromProtobuf(body.token());
}
}

//-----
TokenFreezeTransaction& TokenFreezeTransaction::setAccountId(const AccountId& accountId)
{
requireNotFrozen();
mAccountId = accountId;
return *this;
}

//-----
TokenFreezeTransaction& TokenFreezeTransaction::setTokenId(const TokenId& tokenId)
{
requireNotFrozen();
mTokenId = tokenId;
return *this;
}

//-----
proto::Transaction TokenFreezeTransaction::makeRequest(const Client& client,
const std::shared_ptr<internal::Node>&) const
{
proto::TransactionBody transactionBody = generateTransactionBody(client);
transactionBody.set_allocated_tokenfreeze(build());

return signTransaction(transactionBody, client);
}

//-----
grpc::Status TokenFreezeTransaction::submitRequest(const Client& client,
const std::chrono::system_clock::time_point& deadline,
const std::shared_ptr<internal::Node>& node,
proto::TransactionResponse* response) const
{
return node->submitTransaction(
proto::TransactionBody::DataCase::kTokenFreeze, makeRequest(client, node), deadline, response);
}

//-----
proto::TokenFreezeAccountTransactionBody* TokenFreezeTransaction::build() const
{
auto body = std::make_unique<proto::TokenFreezeAccountTransactionBody>();

if (!(mAccountId == AccountId()))
{
body->set_allocated_account(mAccountId.toProtobuf().release());
}

if (!(mTokenId == TokenId()))
{
body->set_allocated_token(mTokenId.toProtobuf().release());
}

return body.release();
}

} // namespace Hedera
7 changes: 6 additions & 1 deletion sdk/main/src/Transaction.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "TokenDeleteTransaction.h"
#include "TokenDissociateTransaction.h"
#include "TokenFeeScheduleUpdateTransaction.h"
#include "TokenFreezeTransaction.h"
#include "TokenMintTransaction.h"
#include "TokenUpdateTransaction.h"
#include "TokenWipeTransaction.h"
Expand Down Expand Up @@ -89,7 +90,8 @@ std::pair<int,
TokenWipeTransaction,
TokenBurnTransaction,
TokenDissociateTransaction,
TokenFeeScheduleUpdateTransaction>>
TokenFeeScheduleUpdateTransaction,
TokenFreezeTransaction>>
Transaction<SdkRequestType>::fromBytes(const std::vector<std::byte>& bytes)
{
proto::TransactionBody txBody;
Expand Down Expand Up @@ -179,6 +181,8 @@ Transaction<SdkRequestType>::fromBytes(const std::vector<std::byte>& bytes)
return { 22, TokenDissociateTransaction(txBody) };
case proto::TransactionBody::kTokenFeeScheduleUpdate:
return { 23, TokenFeeScheduleUpdateTransaction(txBody) };
case proto::TransactionBody::kTokenFreeze:
return { 24, TokenFreezeTransaction(txBody) };
default:
throw std::invalid_argument("Type of transaction cannot be determined from input bytes");
}
Expand Down Expand Up @@ -500,6 +504,7 @@ template class Transaction<TokenCreateTransaction>;
template class Transaction<TokenDeleteTransaction>;
template class Transaction<TokenDissociateTransaction>;
template class Transaction<TokenFeeScheduleUpdateTransaction>;
template class Transaction<TokenFreezeTransaction>;
template class Transaction<TokenMintTransaction>;
template class Transaction<TokenUpdateTransaction>;
template class Transaction<TokenWipeTransaction>;
Expand Down
2 changes: 2 additions & 0 deletions sdk/main/src/impl/Node.cc
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,8 @@ grpc::Status Node::submitTransaction(proto::TransactionBody::DataCase funcEnum,
return mTokenStub->dissociateTokens(&context, transaction, response);
case proto::TransactionBody::DataCase::kTokenFeeScheduleUpdate:
return mTokenStub->updateTokenFeeSchedule(&context, transaction, response);
case proto::TransactionBody::DataCase::kTokenFreeze:
return mTokenStub->freezeTokenAccount(&context, transaction, response);
case proto::TransactionBody::DataCase::kTokenMint:
return mTokenStub->mintToken(&context, transaction, response);
case proto::TransactionBody::DataCase::kTokenUpdate:
Expand Down
1 change: 1 addition & 0 deletions sdk/tests/integration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ add_executable(${TEST_PROJECT_NAME}
TokenDeleteTransactionIntegrationTests.cc
TokenDissociateTransactionIntegrationTests.cc
TokenFeeScheduleUpdateTransactionIntegrationTests.cc
TokenFreezeTransactionIntegrationTests.cc
TokenInfoQueryIntegrationTests.cc
TokenMintTransactionIntegrationTests.cc
TokenUpdateTransactionIntegrationTests.cc
Expand Down
Loading

0 comments on commit 885a971

Please sign in to comment.