Skip to content

Commit

Permalink
Ledger: Use representative for change blocks and epoch signer for epo…
Browse files Browse the repository at this point in the history
…ch blocks in `linked_account`
  • Loading branch information
Exxenoz committed Feb 9, 2025
1 parent 507c6e0 commit 6de112d
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 10 deletions.
24 changes: 24 additions & 0 deletions nano/lib/blocks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,19 @@ nano::account nano::block::destination () const noexcept
}
}

nano::account nano::block::representative () const noexcept
{
switch (type ())
{
case nano::block_type::open:
case nano::block_type::change:
case nano::block_type::state:
return representative_field ().value ();
default:
release_assert (false);
}
}

nano::block_hash nano::block::source () const noexcept
{
release_assert (has_sideband ());
Expand All @@ -309,6 +322,17 @@ nano::block_hash nano::block::source () const noexcept
}
}

nano::link nano::block::link () const noexcept
{
switch (type ())
{
case nano::block_type::state:
return link_field ().value ();
default:
release_assert (false);
}
}

// TODO - Remove comments below and fixup usages to not need to check .is_zero ()
// std::optional<nano::block_hash> nano::block::previous () const
nano::block_hash nano::block::previous () const noexcept
Expand Down
6 changes: 5 additions & 1 deletion nano/lib/blocks.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,17 @@ class block
nano::account destination () const noexcept;
// Destination account for send blocks
virtual std::optional<nano::account> destination_field () const;
// Returns the link hash or account for state blocks
nano::link link () const noexcept;
// Link field for state blocks
virtual std::optional<nano::link> link_field () const;
// Previous block if field exists or 0
nano::block_hash previous () const noexcept;
// Previous block in chain if the field exists
virtual std::optional<nano::block_hash> previous_field () const = 0;
// Representative field for open/change blocks
// Returns the representative account for open/change/state blocks
nano::account representative () const noexcept;
// Representative field for open/change/state blocks
virtual std::optional<nano::account> representative_field () const;
// Returns the source block hash for open/receive/state blocks that are receives
nano::block_hash source () const noexcept;
Expand Down
39 changes: 30 additions & 9 deletions nano/rpc_test/rpc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1108,21 +1108,25 @@ TEST (rpc, account_history)
request.put ("action", "account_history");
request.put ("account", nano::dev::genesis_key.pub.to_account ());
request.put ("include_linked_account", true);
request.put ("count", 2);
request.put ("count", 3);
request.put ("raw", true);
auto response (wait_response (system, rpc_ctx, request, 10s));
std::vector<std::tuple<std::string, std::string, std::string>> history_l;
auto & history_node (response.get_child ("history"));
for (auto i (history_node.begin ()), n (history_node.end ()); i != n; ++i)
{
history_l.push_back (std::make_tuple (i->second.get<std::string> ("type"), i->second.get<std::string> ("hash"), i->second.get<std::string> ("linked_account")));
history_l.push_back (std::make_tuple (i->second.get<std::string> ("subtype"), i->second.get<std::string> ("hash"), i->second.get<std::string> ("linked_account")));
}
ASSERT_EQ (2, history_node.size ());
ASSERT_EQ ("receive", std::get<0> (history_l[0]));
ASSERT_EQ (ureceive->hash ().to_string (), std::get<1> (history_l[0]));
ASSERT_EQ (usend->account ().to_account (), std::get<2> (history_l[0]));
ASSERT_EQ ("send", std::get<0> (history_l[1]));
ASSERT_EQ (usend->hash ().to_string (), std::get<1> (history_l[1]));
ASSERT_EQ (ureceive->account ().to_account (), std::get<2> (history_l[1]));
ASSERT_EQ (3, history_node.size ());
ASSERT_EQ ("change", std::get<0> (history_l[0]));
ASSERT_EQ (uchange->hash ().to_string (), std::get<1> (history_l[0]));
ASSERT_EQ (uchange->representative ().to_account (), std::get<2> (history_l[0]));
ASSERT_EQ ("receive", std::get<0> (history_l[1]));
ASSERT_EQ (ureceive->hash ().to_string (), std::get<1> (history_l[1]));
ASSERT_EQ (usend->account ().to_account (), std::get<2> (history_l[1]));
ASSERT_EQ ("send", std::get<0> (history_l[2]));
ASSERT_EQ (usend->hash ().to_string (), std::get<1> (history_l[2]));
ASSERT_EQ (ureceive->account ().to_account (), std::get<2> (history_l[2]));
}

// Test filtering
Expand Down Expand Up @@ -4194,6 +4198,14 @@ TEST (rpc, block_info)
.work (*node1->work_generate_blocking (key.pub))
.build ();
ASSERT_EQ (nano::block_status::progress, node1->process (open));
auto change = builder
.change ()
.previous (open->hash ())
.representative (nano::dev::genesis_key.pub)
.sign (key.prv, key.pub)
.work (*node1->work_generate_blocking (open->hash ()))
.build ();
ASSERT_EQ (nano::block_status::progress, node1->process (change));
auto const rpc_ctx = add_rpc (system, node1);

// Test successor
Expand Down Expand Up @@ -4239,6 +4251,15 @@ TEST (rpc, block_info)
auto response (wait_response (system, rpc_ctx, request));
ASSERT_EQ (response.get<std::string> ("linked_account"), send->account ().to_account ());
}
// Test include_linked_account - change block
{
boost::property_tree::ptree request;
request.put ("action", "block_info");
request.put ("hash", change->hash ().to_string ());
request.put ("include_linked_account", "true");
auto response (wait_response (system, rpc_ctx, request));
ASSERT_EQ (response.get<std::string> ("linked_account"), change->representative ().to_account ());
}
}

TEST (rpc, block_info_pruning)
Expand Down
8 changes: 8 additions & 0 deletions nano/secure/ledger.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1180,6 +1180,14 @@ std::optional<nano::account> nano::ledger::linked_account (secure::transaction c
{
return any.block_account (transaction, block.source ());
}
else if (block.is_change ())
{
return block.representative ();
}
else if (block.is_epoch ())
{
return epoch_signer (block.link ());
}

return std::nullopt;
}
Expand Down

0 comments on commit 6de112d

Please sign in to comment.