Skip to content

Commit 4c5fa95

Browse files
[release/5.x] Cherry pick: Consolidate single execution path for begin_private_recovery() (#6912) (#6948)
Co-authored-by: Eddy Ashton <edashton@microsoft.com>
1 parent 210e059 commit 4c5fa95

4 files changed

Lines changed: 48 additions & 79 deletions

File tree

src/node/node_state.h

Lines changed: 22 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,6 @@ namespace ccf
147147
std::vector<ccf::kv::Version> view_history;
148148
::consensus::Index last_recovered_signed_idx = 0;
149149
RecoveredEncryptedLedgerSecrets recovered_encrypted_ledger_secrets = {};
150-
LedgerSecretsMap recovered_ledger_secrets = {};
151150
::consensus::Index last_recovered_idx = 0;
152151
static const size_t recovery_batch_size = 100;
153152

@@ -1147,7 +1146,6 @@ namespace ccf
11471146
// Open the service
11481147
if (consensus->can_replicate())
11491148
{
1150-
setup_one_off_secret_hook();
11511149
auto tx = network.tables->create_tx();
11521150

11531151
// Clear recovery shares that were submitted to initiate the recovery
@@ -1493,18 +1491,24 @@ namespace ccf
14931491
}
14941492
}
14951493

1494+
// Decrypts chain of ledger secrets, and writes those to the ledger
1495+
// encrypted for each node. On a commit hook for this write, each node
1496+
// (including this one!) will begin_private_recovery().
14961497
void initiate_private_recovery(ccf::kv::Tx& tx) override
14971498
{
14981499
std::lock_guard<pal::Mutex> guard(lock);
14991500
sm.expect(NodeStartupState::partOfPublicNetwork);
15001501

1501-
recovered_ledger_secrets = share_manager.restore_recovery_shares_info(
1502-
tx, recovered_encrypted_ledger_secrets);
1502+
LedgerSecretsMap recovered_ledger_secrets =
1503+
share_manager.restore_recovery_shares_info(
1504+
tx, recovered_encrypted_ledger_secrets);
15031505

15041506
// Broadcast decrypted ledger secrets to other nodes for them to
15051507
// initiate private recovery too
15061508
LedgerSecretsBroadcast::broadcast_some(
1507-
network, self, tx, recovered_ledger_secrets);
1509+
InternalTablesAccess::get_trusted_nodes(tx),
1510+
tx.wo(network.secrets),
1511+
std::move(recovered_ledger_secrets));
15081512
}
15091513

15101514
//
@@ -1699,7 +1703,9 @@ namespace ccf
16991703
auto new_ledger_secret = make_ledger_secret();
17001704
share_manager.issue_recovery_shares(tx, new_ledger_secret);
17011705
LedgerSecretsBroadcast::broadcast_new(
1702-
network, tx, std::move(new_ledger_secret));
1706+
InternalTablesAccess::get_trusted_nodes(tx),
1707+
tx.wo(network.secrets),
1708+
std::move(new_ledger_secret));
17031709

17041710
return true;
17051711
}
@@ -1991,14 +1997,11 @@ namespace ccf
19911997
threading::get_current_thread_id(), std::move(msg));
19921998
}
19931999

1994-
void backup_initiate_private_recovery()
2000+
void begin_private_recovery()
19952001
{
1996-
if (!consensus->is_backup())
1997-
return;
1998-
19992002
sm.expect(NodeStartupState::partOfPublicNetwork);
20002003

2001-
LOG_INFO_FMT("Initiating end of recovery (backup)");
2004+
LOG_INFO_FMT("Beginning private recovery");
20022005

20032006
setup_private_recovery_store();
20042007

@@ -2121,42 +2124,18 @@ namespace ccf
21212124
// recovery protocol (backup only)
21222125
network.ledger_secrets->restore_historical(
21232126
std::move(restored_ledger_secrets));
2124-
backup_initiate_private_recovery();
2127+
begin_private_recovery();
21252128
return;
21262129
}
21272130
}
2128-
}));
2129-
2130-
network.tables->set_global_hook(
2131-
network.encrypted_submitted_shares.get_name(),
2132-
network.encrypted_submitted_shares.wrap_commit_hook(
2133-
[this](
2134-
ccf::kv::Version hook_version,
2135-
const EncryptedSubmittedShares::Write& w) {
2136-
// Initiate recovery procedure from global hook, once all recovery
2137-
// shares have been submitted (i.e. recovered_ledger_secrets is
2138-
// set)
2139-
if (!recovered_ledger_secrets.empty())
2140-
{
2141-
network.ledger_secrets->restore_historical(
2142-
std::move(recovered_ledger_secrets));
21432131

2144-
LOG_INFO_FMT("Initiating end of recovery (primary)");
2145-
2146-
setup_private_recovery_store();
2147-
reset_recovery_hook();
2148-
2149-
// Start reading private security domain of ledger
2150-
last_recovered_idx = recovery_store->current_version();
2151-
read_ledger_entries(
2152-
last_recovered_idx + 1,
2153-
last_recovered_idx + recovery_batch_size);
2154-
2155-
sm.advance(NodeStartupState::readingPrivateLedger);
2156-
}
2157-
2158-
return;
2159-
}));
2132+
LOG_INFO_FMT(
2133+
"Found no ledger secrets for this node ({}) in global commit hook "
2134+
"for {} @ {}",
2135+
self,
2136+
network.secrets.get_name(),
2137+
hook_version);
2138+
}));
21602139

21612140
network.tables->set_global_hook(
21622141
network.nodes.get_name(),

src/node/secret_broadcast.h

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include "ccf/crypto/key_wrap.h"
66
#include "ccf/crypto/rsa_key_pair.h"
77
#include "ledger_secrets.h"
8-
#include "network_state.h"
98
#include "service/internal_tables_access.h"
109

1110
#include <optional>
@@ -15,17 +14,16 @@ namespace ccf
1514
class LedgerSecretsBroadcast
1615
{
1716
public:
17+
using SecretsWriteHandle = ccf::Secrets::WriteOnlyHandle;
18+
1819
static void broadcast_some(
19-
NetworkState& network,
20-
NodeId self,
21-
ccf::kv::Tx& tx,
20+
std::map<NodeId, NodeInfo>&& nodes,
21+
SecretsWriteHandle* secrets,
2222
const LedgerSecretsMap& some_ledger_secrets)
2323
{
24-
auto secrets = tx.rw(network.secrets);
25-
2624
LedgerSecretsForNodes secrets_for_nodes;
2725

28-
for (auto [nid, ni] : InternalTablesAccess::get_trusted_nodes(tx, self))
26+
for (auto [nid, ni] : nodes)
2927
{
3028
std::vector<EncryptedLedgerSecret> ledger_secrets_for_node;
3129

@@ -46,15 +44,13 @@ namespace ccf
4644
}
4745

4846
static void broadcast_new(
49-
NetworkState& network,
50-
ccf::kv::Tx& tx,
47+
std::map<NodeId, NodeInfo>&& nodes,
48+
SecretsWriteHandle* secrets,
5149
LedgerSecretPtr&& new_ledger_secret)
5250
{
53-
auto secrets = tx.rw(network.secrets);
54-
5551
LedgerSecretsForNodes secrets_for_nodes;
5652

57-
for (auto [nid, ni] : InternalTablesAccess::get_trusted_nodes(tx))
53+
for (auto [nid, ni] : nodes)
5854
{
5955
std::vector<EncryptedLedgerSecret> ledger_secrets_for_node;
6056

src/service/internal_tables_access.h

Lines changed: 16 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -282,36 +282,30 @@ namespace ccf
282282
node->put(id, node_info);
283283
}
284284

285-
static auto get_trusted_nodes(
286-
ccf::kv::ReadOnlyTx& tx,
287-
std::optional<NodeId> self_to_exclude = std::nullopt)
285+
static std::map<NodeId, NodeInfo> get_trusted_nodes(ccf::kv::ReadOnlyTx& tx)
288286
{
289-
// Returns the list of trusted nodes. If self_to_exclude is set,
290-
// self_to_exclude is not included in the list of returned nodes.
291287
std::map<NodeId, NodeInfo> active_nodes;
292288

293289
auto nodes = tx.ro<ccf::Nodes>(Tables::NODES);
294290

295-
nodes->foreach([&active_nodes, &nodes, self_to_exclude](
296-
const NodeId& nid, const NodeInfo& ni) {
297-
if (
298-
ni.status == ccf::NodeStatus::TRUSTED &&
299-
(!self_to_exclude.has_value() || self_to_exclude.value() != nid))
300-
{
301-
active_nodes[nid] = ni;
302-
}
303-
else if (ni.status == ccf::NodeStatus::RETIRED)
304-
{
305-
// If a node is retired, but knowledge of their retirement has not yet
306-
// been globally committed, they are still considered active.
307-
auto cni = nodes->get_globally_committed(nid);
308-
if (cni.has_value() && !cni->retired_committed)
291+
nodes->foreach(
292+
[&active_nodes, &nodes](const NodeId& nid, const NodeInfo& ni) {
293+
if (ni.status == ccf::NodeStatus::TRUSTED)
309294
{
310295
active_nodes[nid] = ni;
311296
}
312-
}
313-
return true;
314-
});
297+
else if (ni.status == ccf::NodeStatus::RETIRED)
298+
{
299+
// If a node is retired, but knowledge of their retirement has not
300+
// yet been globally committed, they are still considered active.
301+
auto cni = nodes->get_globally_committed(nid);
302+
if (cni.has_value() && !cni->retired_committed)
303+
{
304+
active_nodes[nid] = ni;
305+
}
306+
}
307+
return true;
308+
});
315309

316310
return active_nodes;
317311
}

src/service/tables/secrets.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ namespace ccf
3131
using EncryptedLedgerSecrets = std::vector<EncryptedLedgerSecret>;
3232
using LedgerSecretsForNodes = std::map<NodeId, EncryptedLedgerSecrets>;
3333

34-
// This map is used to communicate encrypted ledger secrets from the primary
35-
// to the backups during recovery (past secrets) and re-keying (new secret)
34+
// This map is used to broadcast encrypted ledger secrets to all nodes, during
35+
// recovery (past secrets) and re-keying (new secret)
3636
using Secrets = ServiceValue<LedgerSecretsForNodes>;
3737
namespace Tables
3838
{

0 commit comments

Comments
 (0)