25#include <merklecpp/merklecpp.h>
29struct formatter<
ccf::kv::TxHistory::RequestID>
31 template <
typename ParseContext>
32 constexpr auto parse(ParseContext& ctx)
37 template <
typename FormatContext>
41 ctx.out(),
"<RID {0}, {1}>", std::get<0>(p), std::get<1>(p));
56#ifdef OVERRIDE_MAX_HISTORY_LEN
109 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
110 auto serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
111 ccf::Tables::SERIALISED_MERKLE_TREE);
113 signatures->put(sig_value);
114 serialised_tree->put({});
115 return sig.commit_reserved();
136 void append(
const std::vector<uint8_t>&)
override
143 std::optional<ccf::kv::Term> term_of_next_version_ =
144 std::nullopt)
override
183 LOG_DEBUG_FMT(
"Issuing signature at {}.{}", txid.term, txid.version);
185 txid, std::make_unique<NullTxHistoryPendingTx>(txid, store,
id),
true);
197 std::tuple<ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
226 static constexpr size_t sha256_byte_size = 32;
227 static inline void sha256_history(
228 const merkle::HashT<sha256_byte_size>& l,
229 const merkle::HashT<sha256_byte_size>& r,
230 merkle::HashT<sha256_byte_size>& out)
233 uint8_t block[sha256_byte_size * 2];
234 memcpy(&block[0], l.bytes, sha256_byte_size);
235 memcpy(&block[sha256_byte_size], r.bytes, sha256_byte_size);
240 using HistoryTree = merkle::TreeT<sha256_byte_size, ccf::sha256_history>;
245 HistoryTree::Hash root;
246 std::shared_ptr<HistoryTree::Path> path =
nullptr;
251 Proof(
const std::vector<uint8_t>& v)
254 root.deserialise(v, position);
255 path = std::make_shared<HistoryTree::Path>(v, position);
271 path = tree->path(index);
278 if (path->max_index() > tree->max_index())
282 else if (tree->max_index() == path->max_index())
284 return tree->root() == root && path->verify(root);
288 auto past_root = tree->past_root(path->max_index());
289 return path->verify(*past_root);
293 std::vector<uint8_t>
to_v()
const
295 std::vector<uint8_t> v;
325 endorsed_cert(endorsed_cert_)
332 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
333 auto serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
334 ccf::Tables::SERIALISED_MERKLE_TREE);
337 std::vector<uint8_t> primary_sig;
339 primary_sig = kp.
sign_hash(root.
h.data(), root.
h.size());
350 signatures->put(sig_value);
352 return sig.commit_reserved();
370 tree =
new HistoryTree(merkle::Hash(first_hash.h));
387 tree->insert(merkle::Hash(hash.
h));
392 const merkle::Hash& root = tree->root();
394 std::copy(root.bytes, root.bytes + root.size(), result.
h.begin());
408 tree->flush_to(index);
414 tree->retract_to(index);
421 throw std::logic_error(fmt::format(
422 "Cannot produce proof for {}: index is older than first index {}, "
423 "and has been flushed from memory",
429 throw std::logic_error(fmt::format(
430 "Cannot produce proof for {}: index is later than last index {}",
434 return Proof(tree, index);
444 LOG_TRACE_FMT(
"mt_serialize_size {}", tree->serialised_size());
445 std::vector<uint8_t> output;
446 tree->serialise(output);
453 "mt_serialize_size ({},{}) {}",
456 tree->serialised_size(from, to));
457 std::vector<uint8_t> output;
458 tree->serialise(from, to, output);
464 return tree->min_index();
469 return tree->max_index();
479 const merkle::Hash& leaf = tree->leaf(index);
481 std::copy(leaf.bytes, leaf.bytes + leaf.size(), result.
h.begin());
491 T replicated_state_tree;
495 std::vector<uint8_t> cose_cert_cached{};
497 std::optional<::threading::TaskQueue::TimerEntry>
498 emit_signature_timer_entry = std::nullopt;
499 size_t sig_tx_interval;
500 size_t sig_ms_interval;
506 std::optional<ccf::crypto::Pem> endorsed_cert = std::nullopt;
513 size_t sig_tx_interval_ = 0,
514 size_t sig_ms_interval_ = 0,
515 bool signature_timer =
false) :
519 sig_tx_interval(sig_tx_interval_),
520 sig_ms_interval(sig_ms_interval_)
536 auto emit_sig_msg = std::make_unique<::threading::Tmsg<EmitSigMsg>>(
537 [](std::unique_ptr<::threading::Tmsg<EmitSigMsg>> msg) {
538 auto self = msg->data.self;
540 std::unique_lock<ccf::pal::Mutex> mguard(
541 self->signature_lock, std::defer_lock);
543 bool should_emit_signature =
false;
545 if (mguard.try_lock())
547 auto consensus = self->store.get_consensus();
550 auto sig_disp =
consensus->get_signature_disposition();
559 if (self->store.committable_gap() > 0)
561 should_emit_signature =
true;
567 should_emit_signature =
true;
574 if (should_emit_signature)
576 msg->data.self->emit_signature();
579 self->emit_signature_timer_entry =
581 std::move(msg), std::chrono::milliseconds(self->sig_ms_interval));
585 emit_signature_timer_entry =
587 std::move(emit_sig_msg), std::chrono::milliseconds(sig_ms_interval));
592 if (emit_signature_timer_entry.has_value())
595 *emit_signature_timer_entry);
605 const std::vector<uint8_t>& hash_at_snapshot)
override
611 auto tree_h = tx.template ro<ccf::SerialisedMerkleTree>(
612 ccf::Tables::SERIALISED_MERKLE_TREE);
613 auto tree = tree_h->get();
614 if (!tree.has_value())
622 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
625 !replicated_state_tree.in_range(1),
626 "Tree is not empty before initialising from snapshot");
628 replicated_state_tree.deserialise(tree.value());
632 hash_at_snapshot.begin(),
635 replicated_state_tree.append(hash);
641 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
642 return replicated_state_tree.get_root();
645 std::tuple<ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
648 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
650 {term_of_last_version,
652 replicated_state_tree.get_root(),
653 term_of_next_version};
661 tx.template ro<ccf::Signatures>(ccf::Tables::SIGNATURES);
662 auto sig = signatures->get();
663 if (!sig.has_value())
671 if (!verify_node_signature(tx, sig->node, sig->sig, root))
681 auto cose_signatures =
682 tx.template ro<ccf::CoseSignatures>(ccf::Tables::COSE_SIGNATURES);
683 auto cose_sig = cose_signatures->get();
685 if (!cose_sig.has_value())
690 auto service = tx.template ro<ccf::Service>(Tables::SERVICE);
691 auto service_info = service->get();
693 if (!service_info.has_value())
695 LOG_FAIL_FMT(
"No service key found to verify the signature");
699 const auto raw_cert = service_info->cert.raw();
700 const std::vector<const uint8_t> root_hash{
701 root.h.data(), root.h.data() + root.h.size()};
703 return cose_verifier_cached(raw_cert)->verify_detached(
704 cose_sig.value(), root_hash);
709 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
710 if (to <= replicated_state_tree.end_index())
712 return replicated_state_tree.serialise(
713 replicated_state_tree.begin_index(), to);
725 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
726 term_of_last_version = t;
727 term_of_next_version = t;
733 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
735 term_of_last_version = tx_id.
term;
736 term_of_next_version = term_of_next_version_;
737 replicated_state_tree.retract(tx_id.
version);
738 log_hash(replicated_state_tree.get_root(),
ROLLBACK);
743 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
750 log_hash(replicated_state_tree.get_root(),
COMPACT);
757 std::unique_lock<ccf::pal::Mutex> mguard(
signature_lock, std::defer_lock);
779 if (!endorsed_cert.has_value())
781 throw std::logic_error(
782 fmt::format(
"No endorsed certificate set to emit signature"));
787 LOG_DEBUG_FMT(
"Signed at {} in view: {}", txid.version, txid.term);
792 txid, store, *
this,
id, kp, endorsed_cert.value()),
798 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
799 return replicated_state_tree.get_proof(index).to_v();
805 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
806 return replicated_state_tree.verify(proof);
811 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
812 auto leaf = replicated_state_tree.get_leaf(index);
813 return {leaf.h.begin(), leaf.h.end()};
816 void append(
const std::vector<uint8_t>& data)
override
820 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
821 replicated_state_tree.append(rh);
826 std::optional<ccf::kv::Term> expected_term_of_next_version =
827 std::nullopt)
override
830 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
831 if (expected_term_of_next_version.has_value())
833 if (expected_term_of_next_version.value() != term_of_next_version)
838 replicated_state_tree.append(digest);
843 endorsed_cert = cert;
848 const std::vector<uint8_t>& cert)
850 if (cert != cose_cert_cached)
852 cose_cert_cached = cert;
856 return cose_verifier;
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
void set_term(ccf::kv::Term t) override
Definition history.h:721
bool verify_proof(const std::vector< uint8_t > &v) override
Definition history.h:802
HashedTxHistory(ccf::kv::Store &store_, const NodeId &id_, ccf::crypto::KeyPair &kp_, size_t sig_tx_interval_=0, size_t sig_ms_interval_=0, bool signature_timer=false)
Definition history.h:509
void set_endorsed_certificate(const ccf::crypto::Pem &cert) override
Definition history.h:841
void compact(ccf::kv::Version v) override
Definition history.h:741
std::vector< uint8_t > get_proof(ccf::kv::Version index) override
Definition history.h:796
ccf::pal::Mutex signature_lock
Definition history.h:753
std::vector< uint8_t > serialise_tree(size_t to) override
Definition history.h:707
void append(const std::vector< uint8_t > &data) override
Definition history.h:816
~HashedTxHistory()
Definition history.h:590
std::tuple< ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term > get_replicated_state_txid_and_root() override
Definition history.h:646
void start_signature_emit_timer() override
Definition history.h:528
void set_node_id(const NodeId &id_)
Definition history.h:599
void try_emit_signature() override
Definition history.h:755
bool verify_root_signatures(bool has_cose) override
Definition history.h:656
void emit_signature() override
Definition history.h:770
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:639
std::vector< uint8_t > get_raw_leaf(uint64_t index) override
Definition history.h:809
void append_entry(const ccf::crypto::Sha256Hash &digest, std::optional< ccf::kv::Term > expected_term_of_next_version=std::nullopt) override
Definition history.h:824
void rollback(const ccf::kv::TxID &tx_id, ccf::kv::Term term_of_next_version_) override
Definition history.h:730
bool init_from_snapshot(const std::vector< uint8_t > &hash_at_snapshot) override
Definition history.h:604
ccf::kv::PendingTxInfo call() override
Definition history.h:328
MerkleTreeHistoryPendingTx(ccf::kv::TxID txid_, ccf::kv::Store &store_, ccf::kv::TxHistory &history_, const NodeId &id_, ccf::crypto::KeyPair &kp_, ccf::crypto::Pem &endorsed_cert_)
Definition history.h:313
void deserialise(const std::vector< uint8_t > &serialised)
Definition history.h:379
void flush(uint64_t index)
Definition history.h:405
ccf::crypto::Sha256Hash get_root() const
Definition history.h:390
std::vector< uint8_t > serialise(size_t from, size_t to)
Definition history.h:450
ccf::crypto::Sha256Hash get_leaf(uint64_t index)
Definition history.h:477
MerkleTreeHistory(const std::vector< uint8_t > &serialised)
Definition history.h:363
MerkleTreeHistory(ccf::crypto::Sha256Hash first_hash={})
Definition history.h:368
bool verify(const Proof &r)
Definition history.h:437
MerkleTreeHistory(MerkleTreeHistory const &)=delete
Proof get_proof(uint64_t index)
Definition history.h:417
std::vector< uint8_t > serialise()
Definition history.h:442
uint64_t end_index()
Definition history.h:467
void operator=(const MerkleTreeHistory &rhs)
Definition history.h:398
void append(const ccf::crypto::Sha256Hash &hash)
Definition history.h:385
uint64_t begin_index()
Definition history.h:462
void retract(uint64_t index)
Definition history.h:411
~MerkleTreeHistory()
Definition history.h:373
bool in_range(uint64_t index)
Definition history.h:472
ccf::kv::PendingTxInfo call() override
Definition history.h:105
NullTxHistoryPendingTx(ccf::kv::TxID txid_, ccf::kv::Store &store_, const NodeId &id_)
Definition history.h:98
void set_endorsed_certificate(const ccf::crypto::Pem &cert) override
Definition history.h:221
void try_emit_signature() override
Definition history.h:188
void compact(ccf::kv::Version) override
Definition history.h:168
ccf::crypto::Sha256Hash get_replicated_state_root() override
Definition history.h:192
ccf::kv::Term term_of_last_version
Definition history.h:126
void start_signature_emit_timer() override
Definition history.h:190
void rollback(const ccf::kv::TxID &tx_id, ccf::kv::Term commit_term_) override
Definition history.h:160
std::tuple< ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term > get_replicated_state_txid_and_root() override
Definition history.h:198
bool init_from_snapshot(const std::vector< uint8_t > &) override
Definition history.h:170
std::vector< uint8_t > serialise_tree(size_t) override
Definition history.h:216
bool verify_root_signatures(bool has_cose) override
Definition history.h:149
void emit_signature() override
Definition history.h:180
ccf::kv::Term term_of_next_version
Definition history.h:127
bool verify_proof(const std::vector< uint8_t > &) override
Definition history.h:211
void append(const std::vector< uint8_t > &) override
Definition history.h:136
std::vector< uint8_t > get_proof(ccf::kv::Version) override
Definition history.h:206
void set_term(ccf::kv::Term t) override
Definition history.h:154
void append_entry(const ccf::crypto::Sha256Hash &digest, std::optional< ccf::kv::Term > term_of_next_version_=std::nullopt) override
Definition history.h:141
ccf::kv::Version version
Definition history.h:125
NullTxHistory(ccf::kv::Store &store_, const NodeId &id_, ccf::crypto::KeyPair &)
Definition history.h:130
std::vector< uint8_t > get_raw_leaf(uint64_t) override
Definition history.h:175
std::shared_ptr< HistoryTree::Path > get_path()
Definition history.h:263
const HistoryTree::Hash & get_root() const
Definition history.h:258
std::vector< uint8_t > to_v() const
Definition history.h:293
Proof(HistoryTree *tree, uint64_t index)
Definition history.h:268
Proof(const std::vector< uint8_t > &v)
Definition history.h:251
Proof(const Proof &)=delete
Proof()
Definition history.h:249
bool verify(HistoryTree *tree) const
Definition history.h:276
virtual std::vector< uint8_t > sign_hash(const uint8_t *hash, size_t hash_size) const =0
Definition sha256_hash.h:16
Representation h
Definition sha256_hash.h:20
static constexpr size_t SIZE
Definition sha256_hash.h:18
Definition kv_types.h:503
ReservedTx create_reserved_tx(const TxID &tx_id)
Definition store.h:1256
ReadOnlyTx create_read_only_tx() override
Definition store.h:1231
size_t committable_gap() override
Definition store.h:1085
TxID next_txid() override
Definition store.h:1077
std::shared_ptr< Consensus > get_consensus() override
Definition store.h:184
CommitResult commit(const TxID &txid, std::unique_ptr< PendingTx > pending_tx, bool globally_committable) override
Definition store.h:874
Definition kv_types.h:366
std::tuple< size_t, size_t > RequestID
Definition kv_types.h:370
virtual std::vector< uint8_t > serialise_tree(size_t to)=0
virtual ccf::crypto::Sha256Hash get_replicated_state_root()=0
static ThreadMessaging & instance()
Definition thread_messaging.h:278
bool cancel_timer_task(TaskQueue::TimerEntry timer_entry)
Definition thread_messaging.h:327
TaskQueue::TimerEntry add_task_after(std::unique_ptr< Tmsg< Payload > > msg, std::chrono::milliseconds ms)
Definition thread_messaging.h:320
#define LOG_TRACE_FMT
Definition logger.h:378
#define LOG_DEBUG_FMT
Definition logger.h:380
#define LOG_FAIL_FMT
Definition logger.h:396
void openssl_sha256(const std::span< const uint8_t > &data, uint8_t *h)
Definition hash.cpp:83
std::unique_ptr< COSEVerifier > COSEVerifierUniquePtr
Definition cose_verifier.h:25
COSEVerifierUniquePtr make_cose_verifier_from_cert(const std::vector< uint8_t > &cert)
Definition cose_verifier.cpp:216
uint64_t Term
Definition kv_types.h:46
uint64_t Version
Definition version.h:8
std::mutex Mutex
Definition locking.h:17
Definition app_interface.h:15
merkle::TreeT< sha256_byte_size, ccf::sha256_history > HistoryTree
Definition history.h:240
constexpr int MAX_HISTORY_LEN
Definition history.h:59
HashedTxHistory< MerkleTreeHistory > MerkleTxHistory
Definition history.h:860
HashOp
Definition history.h:49
@ COMPACT
Definition history.h:53
@ VERIFY
Definition history.h:51
@ APPEND
Definition history.h:50
@ ROLLBACK
Definition history.h:52
Definition consensus_types.h:23
std::ostream & operator<<(std::ostream &os, ccf::NodeStartupState s)
Definition node_startup_state.h:34
Definition signatures.h:14
Definition kv_types.h:481
Version version
Definition kv_types.h:52
Term term
Definition kv_types.h:51
auto format(const ccf::kv::TxHistory::RequestID &p, FormatContext &ctx) const
Definition history.h:38
constexpr auto parse(ParseContext &ctx)
Definition history.h:32