Skip to content

Improve block field functions by accessing sideband information internally#4465

Merged
clemahieu merged 17 commits intonanocurrency:developfrom
clemahieu:block_fields
Mar 9, 2024
Merged

Improve block field functions by accessing sideband information internally#4465
clemahieu merged 17 commits intonanocurrency:developfrom
clemahieu:block_fields

Conversation

@clemahieu
Copy link
Copy Markdown
Contributor

This change moves the responsibility of determining if a field is in the block or in the block's sideband on to the block class.

Previously call sites would need to either inspect the block type or check for a sentinel value to determine where the block field information was stored. This complicates call sites, duplicates code, and could be error prone.

Direct block field access e.g. account/link/destination/balance are suffixed with _field and return an std::optional depending if the block type contains the requested field.

The replacement field functions check block type and determine if the value should be retrieved from the field or the block sideband.

The conversion for each field is done with two commits in order to ensure all call sites are inspected and updated to the new semantics.

  • The first commit changes the return type of of the block field which allowed easy locating / updating of all the call sites through compiler type checking.
  • The second commit renames the direct field access function and adds a helper function to pull the field value or the sideband value depending on block type.

@clemahieu clemahieu requested review from dsiganos and pwojcikdev March 6, 2024 17:58
case nano::block_status::gap_source:
{
const auto account = block.previous ().is_zero () ? block.account ().value () : ledger.account (tx, block.previous ()).value ();
const auto account = block.previous ().is_zero () ? block.account_field ().value () : ledger.account (tx, block.previous ()).value ();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line looks a bit suspicious, it seems to rely on the fact that if both source and previous block is missing, then ledger processing code will return block_status::gap_previous. Otherwise it would crash. No need to do anything, just something that might bite later down the road, with subsequent refactorings.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea it relies on the fact that if previous.is_zero (), then it must be an open or state block and therefore the account field is present. Since the block failed to be inserted it won't have sideband at this point.

pwojcikdev
pwojcikdev previously approved these changes Mar 7, 2024
@clemahieu clemahieu force-pushed the block_fields branch 2 times, most recently from 64e753a to 3ad6992 Compare March 7, 2024 16:11
…y contains the field.

Fixes up call sites that checked against the old sentinel value 0.
Convert many call sites to using ledger::account(block&) when possible.
@clemahieu clemahieu force-pushed the block_fields branch 2 times, most recently from 7fdf312 to ec4706a Compare March 8, 2024 00:22
@clemahieu clemahieu marked this pull request as ready for review March 8, 2024 14:28
{
hashes.push_back (previous);
source = node.ledger.block_source (transaction, *block_d);
source = block_d->source_field ().value_or (block_d->is_send () ? 0 : block_d->link_field ().value_or (0).as_block_hash ());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A short node.ledger.block_source ( .. ) call changed into this relatively long conditional statement, is this intentional?

pwojcikdev
pwojcikdev previously approved these changes Mar 9, 2024
if (sources != 0) // Republish source chain
{
nano::block_hash source (node.ledger.block_source (transaction, *block));
nano::block_hash source = block->source_field ().value_or (block->link_field ().value_or (0).as_block_hash ());
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another line that got more complicated after the refactor than before.

clemahieu added 11 commits March 9, 2024 11:01
…ccesses the account field is renamed to block::account_field.
…ccesses the account field is renamed to block::balance_field.
…estination is created which accesses the the destination field for send blocks.
…ce is moved to block::source which accesses the source field for open/receive/state blocks that are receives.
A specialised variant of is_send for state blocks that do not have sideband was added to dependent_block_visitor so the value can be calculated even if the block does not yet have sideband.
…nge block or a state block with a zero link field.
… number to an account number are replaced with calls to block::destination (). Usages that converted this number to a block_hash are replaced with calls to block::source, and usages that check this number for being an epoch directly access the link field.
…nal depending if the block has the field.

Add block::previous with backwards compatibility and a todo to fix up usages to not check for sentinel values.
@clemahieu clemahieu merged commit 7561a79 into nanocurrency:develop Mar 9, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants