From 330d54b7b629b9270f15dbc0a8258f907c6ab74a Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) Kroshnin" Date: Sun, 6 Oct 2024 21:14:21 +0100 Subject: [PATCH 1/7] QT wallet: properly display state open block in history State open block should be marked as "Receive" --- nano/qt/qt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index b7e1e13be1..9ad16d8324 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -585,7 +585,7 @@ class short_text_visitor : public nano::block_visitor { auto balance (block_a.hashables.balance.number ()); auto previous_balance = ledger.any.block_balance (transaction, block_a.hashables.previous); - if (!previous_balance) + if (!block_a.hashables.previous.is_zero () && !previous_balance) { type = "Unknown (pruned)"; amount = 0; From fe35fd6da5a11c0c490b757227cfe6df5d848dce Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Fri, 25 Oct 2024 17:12:16 +0100 Subject: [PATCH 2/7] Update pruned blocks detection in QT GUI history --- nano/qt/qt.cpp | 73 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 201299bc97..1120103e52 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -585,44 +585,69 @@ class short_text_visitor : public nano::block_visitor { auto balance (block_a.hashables.balance.number ()); auto previous_balance = ledger.any.block_balance (transaction, block_a.hashables.previous); - if (!block_a.hashables.previous.is_zero () && !previous_balance) + // Error to receive previous block balance means that previous block was pruned from the ledger + if ((!previous_balance && block_a.sideband ().details.is_send) || balance < previous_balance.value ().number ()) { - type = "Unknown (pruned)"; + type = "Send"; + account = block_a.hashables.link.as_account (); + if (!previous_balance) + { + type = "Send (pruned)"; + amount = 0; + } + else + { + amount = previous_balance.value ().number () - balance; + } + } + else if (block_a.hashables.link.is_zero ()) + { + debug_assert (!block_a.sideband ().details.is_send && !block_a.sideband ().details.is_receive && !block_a.sideband ().details.is_epoch); + type = "Change"; + account = block_a.hashables.representative; amount = 0; - account = block_a.hashables.account; + if (!previous_balance) + { + type = "Change (pruned)"; + } + else + { + debug_assert (balance == previous_balance); + } } - else if (balance < previous_balance.value ().number ()) + else if (ledger.is_epoch_link (block_a.hashables.link) && block_a.sideband ().details.is_epoch) { - type = "Send"; - amount = previous_balance.value ().number () - balance; - account = block_a.hashables.link.as_account (); + debug_assert (!previous_balance || balance == previous_balance); + type = "Epoch"; + amount = 0; + if (!previous_balance) + { + type = "Epoch (pruned)"; + } + account = ledger.epoch_signer (block_a.hashables.link); } else { - if (block_a.hashables.link.is_zero ()) + debug_assert (block_a.sideband ().details.is_receive); + type = "Receive"; + auto account_l = ledger.any.block_account (transaction, block_a.hashables.link.as_block_hash ()); + if (!account_l) + { + type = "Receive (pruned sender)"; + } + else { - type = "Change"; - account = block_a.hashables.representative; + account = account_l.value (); } - else if (balance == previous_balance && ledger.is_epoch_link (block_a.hashables.link)) + if (!previous_balance) { - type = "Epoch"; - account = ledger.epoch_signer (block_a.hashables.link); + type = "Receive (pruned)"; + amount = 0; } else { - type = "Receive"; - auto account_l = ledger.any.block_account (transaction, block_a.hashables.link.as_block_hash ()); - if (!account_l) - { - type = "Receive (pruned)"; - } - else - { - account = account_l.value (); - } + amount = balance - previous_balance.value ().number (); } - amount = balance - previous_balance.value ().number (); } } nano::secure::transaction const & transaction; From 05bb8d4bfa0809ca77c0ef3f85716547cbf71782 Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Fri, 25 Oct 2024 17:48:27 +0100 Subject: [PATCH 3/7] Update conditions --- nano/qt/qt.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 1120103e52..7674093709 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -620,8 +620,9 @@ class short_text_visitor : public nano::block_visitor debug_assert (!previous_balance || balance == previous_balance); type = "Epoch"; amount = 0; - if (!previous_balance) + if (!previous_balance && !block_a.hashables.previous.is_zero ()) { + // Epoch block with previous balance error is pruned only if it isn't open block for an account type = "Epoch (pruned)"; } account = ledger.epoch_signer (block_a.hashables.link); @@ -641,7 +642,11 @@ class short_text_visitor : public nano::block_visitor } if (!previous_balance) { - type = "Receive (pruned)"; + if (!block_a.hashables.previous.is_zero ()) + { + // Receive block with previous balance error is pruned only if it isn't open block for an account + type = "Receive (pruned)"; + } amount = 0; } else From 28b9f4f36b117dac6c35dd145596140a4d3a00e5 Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Fri, 25 Oct 2024 17:50:11 +0100 Subject: [PATCH 4/7] QT GUI pruning test update --- nano/qt_test/qt.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index b4070ca80e..df102bd1e1 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -580,12 +580,32 @@ TEST (history, pruned_source) ASSERT_EQ (1, ledger.pruning_action (transaction, send1->hash (), 2)); next_pruning = send2->hash (); } + // Genesis account pruned values nano_qt::history history1 (ledger, nano::dev::genesis_key.pub, *wallet); history1.refresh (); ASSERT_EQ (2, history1.model->rowCount ()); + auto type1 (history1.model->item (0, 0)); + ASSERT_EQ ("Receive", type1->text ().toStdString ()); + auto account1 (history1.model->item (0, 1)); + ASSERT_EQ (nano::dev::genesis_key.pub.to_account (), account1->text ().toStdString ()); + auto amount1 (history1.model->item (0, 2)); + ASSERT_EQ ("100", amount1->text ().toStdString ()); + auto type2 (history1.model->item (1, 0)); + ASSERT_EQ ("Send (pruned)", type2->text ().toStdString ()); + auto account2 (history1.model->item (1, 1)); + ASSERT_EQ (key.pub.to_account (), account2->text ().toStdString ()); + auto amount2 (history1.model->item (1, 2)); + ASSERT_EQ ("0", amount2->text ().toStdString ()); + // New account pruned values nano_qt::history history2 (ledger, key.pub, *wallet); history2.refresh (); ASSERT_EQ (1, history2.model->rowCount ()); + auto type3 (history2.model->item (0, 0)); + ASSERT_EQ ("Receive (pruned sender)", type3->text ().toStdString ()); + auto account3 (history2.model->item (0, 1)); + ASSERT_EQ (key.pub.to_account (), account3->text ().toStdString ()); + auto amount3 (history2.model->item (0, 2)); + ASSERT_EQ ("100", amount3->text ().toStdString ()); // Additional legacy test { auto transaction = ledger.tx_begin_write (); From 1cc71dd91a9c013dd9b5d69a6aa177289b177220 Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Sun, 27 Oct 2024 20:07:00 +0000 Subject: [PATCH 5/7] Update QT GUI account history --- nano/qt/qt.cpp | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 9005a0773b..107557f2d9 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -531,6 +531,7 @@ class short_text_visitor : public nano::block_visitor if (!amount_l) { type = "Send (pruned)"; + amount = 0; } else { @@ -542,32 +543,41 @@ class short_text_visitor : public nano::block_visitor type = "Receive"; auto account_l = ledger.any.block_account (transaction, block_a.hashables.source); auto amount_l = ledger.any.block_amount (transaction, block_a.hash ()); - if (!account_l || !amount_l) + if (!account_l) { - type = "Receive (pruned)"; + type = "Receive (pruned source)"; } else { account = account_l.value (); + } + if (!amount_l) + { + type = "Receive (pruned)"; + amount = 0; + } + else + { amount = amount_l.value ().number (); } } void open_block (nano::open_block const & block_a) { type = "Receive"; - if (block_a.hashables.source != ledger.constants.genesis->account ().as_union ()) + if (block_a.hashables.source != ledger.constants.genesis->account ()) { auto account_l = ledger.any.block_account (transaction, block_a.hashables.source); auto amount_l = ledger.any.block_amount (transaction, block_a.hash ()); - if (!account_l || !amount_l) + if (!account_l) { - type = "Receive (pruned)"; + type = "Receive (pruned source)"; } else { account = account_l.value (); - amount = amount_l.value ().number (); } + debug_assert (amount_l); + amount = amount_l.value ().number (); } else { @@ -586,7 +596,7 @@ class short_text_visitor : public nano::block_visitor auto balance (block_a.hashables.balance.number ()); auto previous_balance = ledger.any.block_balance (transaction, block_a.hashables.previous); // Error to receive previous block balance means that previous block was pruned from the ledger - if ((!previous_balance && block_a.sideband ().details.is_send) || balance < previous_balance.value ().number ()) + if ((!previous_balance || balance < previous_balance.value ().number ()) && block_a.sideband ().details.is_send) { type = "Send"; account = block_a.hashables.link.as_account (); @@ -600,9 +610,9 @@ class short_text_visitor : public nano::block_visitor amount = previous_balance.value ().number () - balance; } } - else if (block_a.hashables.link.is_zero ()) + else if (block_a.hashables.link.is_zero () && !block_a.sideband ().details.is_send) { - debug_assert (!block_a.sideband ().details.is_send && !block_a.sideband ().details.is_receive && !block_a.sideband ().details.is_epoch); + debug_assert (!block_a.sideband ().details.is_receive && !block_a.sideband ().details.is_epoch); type = "Change"; account = block_a.hashables.representative; amount = 0; @@ -634,7 +644,7 @@ class short_text_visitor : public nano::block_visitor auto account_l = ledger.any.block_account (transaction, block_a.hashables.link.as_block_hash ()); if (!account_l) { - type = "Receive (pruned sender)"; + type = "Receive (pruned source)"; } else { @@ -646,8 +656,12 @@ class short_text_visitor : public nano::block_visitor { // Receive block with previous balance error is pruned only if it isn't open block for an account type = "Receive (pruned)"; + amount = 0; + } + else + { + amount = balance; } - amount = 0; } else { From 8bd901b5a758ed0bb6591c8d1ca07b9246ca99b4 Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Sun, 27 Oct 2024 20:08:08 +0000 Subject: [PATCH 6/7] Update pruned blocks QT GUI test --- nano/qt_test/qt.cpp | 133 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 120 insertions(+), 13 deletions(-) diff --git a/nano/qt_test/qt.cpp b/nano/qt_test/qt.cpp index df102bd1e1..6e843e60dd 100644 --- a/nano/qt_test/qt.cpp +++ b/nano/qt_test/qt.cpp @@ -572,68 +572,175 @@ TEST (history, pruned_source) ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send1)); auto send2 = std::make_shared (send1->hash (), key.pub, nano::dev::constants.genesis_amount - 200, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (send1->hash ())); ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send2)); - auto receive = std::make_shared (send2->hash (), send1->hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (send2->hash ())); - ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive)); + auto receive1 = std::make_shared (send2->hash (), send1->hash (), nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (send2->hash ())); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive1)); auto open = std::make_shared (send2->hash (), key.pub, key.pub, key.prv, key.pub, *system.work.generate (key.pub)); ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open)); ledger.confirm (transaction, send1->hash ()); ASSERT_EQ (1, ledger.pruning_action (transaction, send1->hash (), 2)); next_pruning = send2->hash (); } + // Set rendering ration to raw units + ASSERT_NE (wallet->rendering_ratio, nano::raw_ratio); + wallet->rendering_ratio = nano::raw_ratio; // Genesis account pruned values nano_qt::history history1 (ledger, nano::dev::genesis_key.pub, *wallet); history1.refresh (); ASSERT_EQ (2, history1.model->rowCount ()); + // Source block send1 is removed auto type1 (history1.model->item (0, 0)); - ASSERT_EQ ("Receive", type1->text ().toStdString ()); + ASSERT_EQ ("Receive (pruned source)", type1->text ().toStdString ()); + // Source block account is unknown auto account1 (history1.model->item (0, 1)); - ASSERT_EQ (nano::dev::genesis_key.pub.to_account (), account1->text ().toStdString ()); + ASSERT_EQ (nano::account (0).to_account (), account1->text ().toStdString ()); + // Amount is known because previous block (send2) isn't removed auto amount1 (history1.model->item (0, 2)); - ASSERT_EQ ("100", amount1->text ().toStdString ()); + ASSERT_EQ ("100 raw", amount1->text ().toStdString ()); + // Last not pruned block in chain (send2) auto type2 (history1.model->item (1, 0)); ASSERT_EQ ("Send (pruned)", type2->text ().toStdString ()); auto account2 (history1.model->item (1, 1)); + // Amount is unknown because previous block (send1) is removed ASSERT_EQ (key.pub.to_account (), account2->text ().toStdString ()); auto amount2 (history1.model->item (1, 2)); - ASSERT_EQ ("0", amount2->text ().toStdString ()); + ASSERT_EQ ("0 raw", amount2->text ().toStdString ()); // New account pruned values nano_qt::history history2 (ledger, key.pub, *wallet); history2.refresh (); ASSERT_EQ (1, history2.model->rowCount ()); auto type3 (history2.model->item (0, 0)); - ASSERT_EQ ("Receive (pruned sender)", type3->text ().toStdString ()); + ASSERT_EQ ("Receive", type3->text ().toStdString ()); + // Source block (send2) account is known auto account3 (history2.model->item (0, 1)); - ASSERT_EQ (key.pub.to_account (), account3->text ().toStdString ()); + ASSERT_EQ (nano::dev::genesis_key.pub.to_account (), account3->text ().toStdString ()); auto amount3 (history2.model->item (0, 2)); - ASSERT_EQ ("100", amount3->text ().toStdString ()); + ASSERT_EQ ("100 raw", amount3->text ().toStdString ()); // Additional legacy test { auto transaction = ledger.tx_begin_write (); ledger.confirm (transaction, next_pruning); ASSERT_EQ (1, ledger.pruning_action (transaction, next_pruning, 2)); } + // Genesis account pruned values history1.refresh (); ASSERT_EQ (1, history1.model->rowCount ()); + auto type4 (history1.model->item (0, 0)); + ASSERT_EQ ("Receive (pruned)", type4->text ().toStdString ()); + auto account4 (history1.model->item (0, 1)); + ASSERT_EQ (nano::account (0).to_account (), account4->text ().toStdString ()); + // Amount is unknown because previous block (send2) is removed + auto amount4 (history1.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount4->text ().toStdString ()); + // New account pruned values history2.refresh (); ASSERT_EQ (1, history2.model->rowCount ()); + auto type5 (history2.model->item (0, 0)); + ASSERT_EQ ("Receive (pruned source)", type5->text ().toStdString ()); + // Source block (send2) account is unknown + auto account5 (history2.model->item (0, 1)); + ASSERT_EQ (nano::account (0).to_account (), account5->text ().toStdString ()); + auto amount5 (history2.model->item (0, 2)); + ASSERT_EQ ("100 raw", amount5->text ().toStdString ()); // Pruning for state blocks. Previous block is pruned, source is pruned { auto transaction = ledger.tx_begin_write (); auto latest (ledger.any.account_head (transaction, nano::dev::genesis_key.pub)); - auto send = std::make_shared (nano::dev::genesis_key.pub, latest, nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - 200, key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (latest)); - ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send)); + auto send3 = std::make_shared (nano::dev::genesis_key.pub, latest, nano::dev::genesis_key.pub, nano::dev::constants.genesis_amount - 200, key.pub, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (latest)); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send3)); auto latest_key (ledger.any.account_head (transaction, key.pub)); - auto receive = std::make_shared (key.pub, latest_key, key.pub, 200, send->hash (), key.prv, key.pub, *system.work.generate (latest_key)); - ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive)); + auto receive2 = std::make_shared (key.pub, latest_key, key.pub, 200, send3->hash (), key.prv, key.pub, *system.work.generate (latest_key)); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, receive2)); ledger.confirm (transaction, latest); ASSERT_EQ (1, ledger.pruning_action (transaction, latest, 2)); ledger.confirm (transaction, latest_key); ASSERT_EQ (1, ledger.pruning_action (transaction, latest_key, 2)); } + // Genesis account pruned values + history1.refresh (); + ASSERT_EQ (1, history1.model->rowCount ()); + auto type6 (history1.model->item (0, 0)); + ASSERT_EQ ("Send (pruned)", type6->text ().toStdString ()); + auto account6 (history1.model->item (0, 1)); + ASSERT_EQ (key.pub.to_account (), account6->text ().toStdString ()); + // Amount is unknown because previous block (receive1) is removed + auto amount6 (history1.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount6->text ().toStdString ()); + // New account pruned values + history2.refresh (); + ASSERT_EQ (1, history2.model->rowCount ()); + auto type7 (history2.model->item (0, 0)); + ASSERT_EQ ("Receive (pruned)", type7->text ().toStdString ()); + // Source block (send3) account is known + auto account7 (history2.model->item (0, 1)); + ASSERT_EQ (nano::dev::genesis_key.pub.to_account (), account7->text ().toStdString ()); + // Amount is unknown because previous block (receive1) is removed + auto amount7 (history2.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount7->text ().toStdString ()); + // Pruning for state blocks. Change state block + { + auto transaction = ledger.tx_begin_write (); + auto latest (ledger.any.account_head (transaction, nano::dev::genesis_key.pub)); + auto change = std::make_shared (nano::dev::genesis_key.pub, latest, key.pub, nano::dev::constants.genesis_amount - 200, 0, nano::dev::genesis_key.prv, nano::dev::genesis_key.pub, *system.work.generate (latest)); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, change)); + ledger.confirm (transaction, latest); + ASSERT_EQ (1, ledger.pruning_action (transaction, latest, 2)); + } + // Genesis account pruned values history1.refresh (); ASSERT_EQ (1, history1.model->rowCount ()); + auto type8 (history1.model->item (0, 0)); + ASSERT_EQ ("Change (pruned)", type8->text ().toStdString ()); + auto account8 (history1.model->item (0, 1)); + ASSERT_EQ (key.pub.to_account (), account8->text ().toStdString ()); + // Amount is 0 for change blocks + auto amount8 (history1.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount8->text ().toStdString ()); + // New account pruned values + history2.refresh (); + ASSERT_EQ (1, history2.model->rowCount ()); + auto type9 (history2.model->item (0, 0)); + ASSERT_EQ ("Receive (pruned)", type9->text ().toStdString ()); + // Source block (send3) account is unknown + auto account9 (history2.model->item (0, 1)); + ASSERT_EQ (nano::account (0).to_account (), account9->text ().toStdString ()); + // Amount is unknown because previous block (receive1) is removed + auto amount9 (history2.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount9->text ().toStdString ()); + // Pruning for state blocks. Open state block + nano::keypair key2; + system.wallet (0)->insert_adhoc (key2.prv); + { + auto transaction = ledger.tx_begin_write (); + auto latest_key (ledger.any.account_head (transaction, key.pub)); + auto send4 = std::make_shared (key.pub, latest_key, key.pub, 100, key2.pub, key.prv, key.pub, *system.work.generate (latest_key)); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, send4)); + auto open2 = std::make_shared (key2.pub, 0, key2.pub, 100, send4->hash (), key2.prv, key2.pub, *system.work.generate (key2.pub)); + ASSERT_EQ (nano::block_status::progress, ledger.process (transaction, open2)); + ledger.confirm (transaction, latest_key); + ASSERT_EQ (1, ledger.pruning_action (transaction, latest_key, 2)); + } + // New account (key) pruned values history2.refresh (); ASSERT_EQ (1, history2.model->rowCount ()); + auto type10 (history2.model->item (0, 0)); + ASSERT_EQ ("Send (pruned)", type10->text ().toStdString ()); + auto account10 (history2.model->item (0, 1)); + ASSERT_EQ (key2.pub.to_account (), account10->text ().toStdString ()); + // Amount is unknown because previous block (receive2) is removed + auto amount10 (history2.model->item (0, 2)); + ASSERT_EQ ("0 raw", amount10->text ().toStdString ()); + // Account (key2) pruned values + nano_qt::history history3 (ledger, key2.pub, *wallet); + history3.refresh (); + ASSERT_EQ (1, history3.model->rowCount ()); + // Type is "Recieve" for open block because source block (send4) isn't removed + auto type11 (history3.model->item (0, 0)); + ASSERT_EQ ("Receive", type11->text ().toStdString ()); + auto account11 (history3.model->item (0, 1)); + ASSERT_EQ (key.pub.to_account (), account11->text ().toStdString ()); + // Amount is known for open blocks + auto amount11 (history3.model->item (0, 2)); + ASSERT_EQ ("100 raw", amount11->text ().toStdString ()); } TEST (wallet, startup_work) From c98f7696beaa6e5dc7dbc53bae35b5d66da0bffc Mon Sep 17 00:00:00 2001 From: "Dani (Sergey) K" Date: Sun, 27 Oct 2024 20:11:52 +0000 Subject: [PATCH 7/7] Update with developer branch changes --- nano/qt/qt.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nano/qt/qt.cpp b/nano/qt/qt.cpp index 107557f2d9..5e23b6cc08 100644 --- a/nano/qt/qt.cpp +++ b/nano/qt/qt.cpp @@ -564,7 +564,7 @@ class short_text_visitor : public nano::block_visitor void open_block (nano::open_block const & block_a) { type = "Receive"; - if (block_a.hashables.source != ledger.constants.genesis->account ()) + if (block_a.hashables.source != ledger.constants.genesis->account ().as_union ()) { auto account_l = ledger.any.block_account (transaction, block_a.hashables.source); auto amount_l = ledger.any.block_amount (transaction, block_a.hash ());