Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
9 changes: 8 additions & 1 deletion src/sdk/main/include/NodeUpdateTransaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,14 @@ class NodeUpdateTransaction : public Transaction<NodeUpdateTransaction>
* The node identified MUST NOT be deleted.
* This value is REQUIRED.
*/
uint64_t mNodeId;
uint64_t mNodeId = 0;

/**
* Flag to track whether nodeId has been explicitly set.
* This is necessary because protobuf uint64 defaults to 0, which cannot distinguish
* between an explicit 0 and an unset value.
*/
bool mNodeIdSet = false;

/**
* A Node account identifier.
Expand Down
9 changes: 9 additions & 0 deletions src/sdk/main/src/NodeUpdateTransaction.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: Apache-2.0
#include "NodeUpdateTransaction.h"
#include "TransactionId.h"
#include "exceptions/IllegalStateException.h"
#include "impl/Node.h"
#include "impl/Utilities.h"

Expand Down Expand Up @@ -31,6 +32,7 @@ NodeUpdateTransaction& NodeUpdateTransaction::setNodeId(uint64_t nodeId)
{
requireNotFrozen();
mNodeId = nodeId;
mNodeIdSet = true;
return *this;
}

Expand Down Expand Up @@ -148,6 +150,7 @@ void NodeUpdateTransaction::initFromSourceTransactionBody()
const aproto::NodeUpdateTransactionBody& body = transactionBody.nodeupdate();

mNodeId = body.node_id();
mNodeIdSet = true;
mAccountId = AccountId::fromProtobuf(body.account_id());

if (body.has_description())
Expand Down Expand Up @@ -191,6 +194,12 @@ void NodeUpdateTransaction::initFromSourceTransactionBody()
//-----
aproto::NodeUpdateTransactionBody* NodeUpdateTransaction::build() const
{
// Validate that nodeId has been explicitly set
if (!mNodeIdSet)
{
throw IllegalStateException("NodeUpdateTransaction requires nodeId to be explicitly set before execution");
}

auto body = std::make_unique<aproto::NodeUpdateTransactionBody>();

body->set_node_id(mNodeId);
Expand Down
60 changes: 60 additions & 0 deletions src/sdk/tests/unit/NodeUpdateTransactionUnitTests.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
// SPDX-License-Identifier: Apache-2.0
#include "AccountId.h"
#include "ED25519PrivateKey.h"
#include "NodeUpdateTransaction.h"
#include "TransactionId.h"
#include "exceptions/IllegalStateException.h"
#include "impl/Utilities.h"

#include <gtest/gtest.h>
Expand Down Expand Up @@ -226,3 +229,60 @@ TEST_F(NodeUpdateTransactionUnitTests, DeleteGrpcWebProxyEndpoint)
// Then
ASSERT_FALSE(transaction.getGrpcWebProxyEndpoint().has_value());
}

//-----
TEST_F(NodeUpdateTransactionUnitTests, SetAndGetNodeId)
{
// Given
uint64_t nodeId = 5;

// When
transaction.setNodeId(nodeId);

// Then
ASSERT_EQ(transaction.getNodeId(), nodeId);
}

//-----
TEST_F(NodeUpdateTransactionUnitTests, ThrowsWhenNodeIdNotSet)
{
// Given
NodeUpdateTransaction tx;
tx.setTransactionId(TransactionId::generate(AccountId(2)));
tx.setNodeAccountIds({ AccountId(3) });
tx.setAccountId(AccountId(100));
tx.setDescription("Test node");

// When / Then
EXPECT_THROW(tx.freeze(),IllegalStateException);
}

//-----
TEST_F(NodeUpdateTransactionUnitTests, SucceedsWhenNodeIdIsSet)
{
// Given
NodeUpdateTransaction tx;
tx.setTransactionId(TransactionId::generate(AccountId(2)));
tx.setNodeAccountIds({ AccountId(3) });
tx.setNodeId(5);
tx.setAccountId(AccountId(100));

// When / Then - should not throw
EXPECT_NO_THROW(tx.freeze());
}

//-----
TEST_F(NodeUpdateTransactionUnitTests, NodeIdSetToZeroIsValid)
{
// Given - nodeId can legitimately be 0 if explicitly set
NodeUpdateTransaction tx;
tx.setTransactionId(TransactionId::generate(AccountId(2)));
tx.setNodeAccountIds({ AccountId(3) });
tx.setNodeId(0);
tx.setAccountId(AccountId(100));

// When / Then - should not throw even with nodeId = 0
EXPECT_NO_THROW(tx.freeze());
EXPECT_EQ(tx.getNodeId(), 0);
}

Loading