CCF
Loading...
Searching...
No Matches
history.h
Go to the documentation of this file.
1// Copyright (c) Microsoft Corporation. All rights reserved.
2// Licensed under the Apache 2.0 License.
3#pragma once
4
6#include "ccf/ds/logger.h"
7#include "ccf/pal/locking.h"
10#include "crypto/openssl/hash.h"
11#include "ds/thread_messaging.h"
12#include "endian.h"
13#include "kv/kv_types.h"
14#include "kv/store.h"
17
18#include <array>
19#include <deque>
20#include <string.h>
21
22#define HAVE_OPENSSL
23// merklecpp traces are off by default, even when CCF tracing is enabled
24// #include "merklecpp_trace.h"
25#include <merklecpp/merklecpp.h>
26
27FMT_BEGIN_NAMESPACE
28template <>
29struct formatter<ccf::kv::TxHistory::RequestID>
30{
31 template <typename ParseContext>
32 constexpr auto parse(ParseContext& ctx)
33 {
34 return ctx.begin();
35 }
36
37 template <typename FormatContext>
38 auto format(const ccf::kv::TxHistory::RequestID& p, FormatContext& ctx) const
39 {
40 return format_to(
41 ctx.out(), "<RID {0}, {1}>", std::get<0>(p), std::get<1>(p));
42 }
43};
44FMT_END_NAMESPACE
45
46namespace ccf
47{
55
56#ifdef OVERRIDE_MAX_HISTORY_LEN
57 constexpr int MAX_HISTORY_LEN = OVERRIDE_MAX_HISTORY_LEN;
58#else
59 constexpr int MAX_HISTORY_LEN = 0;
60#endif
61
62 static std::ostream& operator<<(std::ostream& os, HashOp flag)
63 {
64 switch (flag)
65 {
66 case APPEND:
67 os << "append";
68 break;
69
70 case VERIFY:
71 os << "verify";
72 break;
73
74 case ROLLBACK:
75 os << "rollback";
76 break;
77
78 case COMPACT:
79 os << "compact";
80 break;
81 }
82
83 return os;
84 }
85
86 static inline void log_hash(const ccf::crypto::Sha256Hash& h, HashOp flag)
87 {
88 LOG_TRACE_FMT("History [{}] {}", flag, h);
89 }
90
92 {
93 ccf::kv::TxID txid;
94 ccf::kv::Store& store;
95 NodeId id;
96
97 public:
99 ccf::kv::TxID txid_, ccf::kv::Store& store_, const NodeId& id_) :
100 txid(txid_),
101 store(store_),
102 id(id_)
103 {}
104
106 {
107 auto sig = store.create_reserved_tx(txid);
108 auto signatures =
109 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
110 auto serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
111 ccf::Tables::SERIALISED_MERKLE_TREE);
112 PrimarySignature sig_value(id, txid.version);
113 signatures->put(sig_value);
114 serialised_tree->put({});
115 return sig.commit_reserved();
116 }
117 };
118
120 {
121 ccf::kv::Store& store;
122 NodeId id;
123
124 protected:
128
129 public:
131 ccf::kv::Store& store_, const NodeId& id_, ccf::crypto::KeyPair&) :
132 store(store_),
133 id(id_)
134 {}
135
136 void append(const std::vector<uint8_t>&) override
137 {
138 version++;
139 }
140
142 const ccf::crypto::Sha256Hash& digest,
143 std::optional<ccf::kv::Term> term_of_next_version_ =
144 std::nullopt) override
145 {
146 version++;
147 }
148
149 bool verify_root_signatures(bool has_cose) override
150 {
151 return true;
152 }
153
154 void set_term(ccf::kv::Term t) override
155 {
158 }
159
161 const ccf::kv::TxID& tx_id, ccf::kv::Term commit_term_) override
162 {
163 version = tx_id.version;
165 term_of_next_version = commit_term_;
166 }
167
168 void compact(ccf::kv::Version) override {}
169
170 bool init_from_snapshot(const std::vector<uint8_t>&) override
171 {
172 return true;
173 }
174
175 std::vector<uint8_t> get_raw_leaf(uint64_t) override
176 {
177 return {};
178 }
179
180 void emit_signature() override
181 {
182 auto txid = store.next_txid();
183 LOG_DEBUG_FMT("Issuing signature at {}.{}", txid.term, txid.version);
184 store.commit(
185 txid, std::make_unique<NullTxHistoryPendingTx>(txid, store, id), true);
186 }
187
188 void try_emit_signature() override {}
189
190 void start_signature_emit_timer() override {}
191
193 {
194 return ccf::crypto::Sha256Hash(std::to_string(version));
195 }
196
197 std::tuple<ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
199 {
200 return {
202 ccf::crypto::Sha256Hash(std::to_string(version)),
204 }
205
206 std::vector<uint8_t> get_proof(ccf::kv::Version) override
207 {
208 return {};
209 }
210
211 bool verify_proof(const std::vector<uint8_t>&) override
212 {
213 return true;
214 }
215
216 std::vector<uint8_t> serialise_tree(size_t) override
217 {
218 return {};
219 }
220
221 void set_endorsed_certificate(const ccf::crypto::Pem& cert) override {}
222 };
223
224 // Use optimised CCF openssl_sha256 function to avoid performance regression
225 // on OpenSSL 3.x
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)
231
232 {
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);
236
237 ccf::crypto::openssl_sha256(block, out.bytes);
238 }
239
240 using HistoryTree = merkle::TreeT<sha256_byte_size, ccf::sha256_history>;
241
242 class Proof
243 {
244 private:
245 HistoryTree::Hash root;
246 std::shared_ptr<HistoryTree::Path> path = nullptr;
247
248 public:
249 Proof() {}
250
251 Proof(const std::vector<uint8_t>& v)
252 {
253 size_t position = 0;
254 root.deserialise(v, position);
255 path = std::make_shared<HistoryTree::Path>(v, position);
256 }
257
258 const HistoryTree::Hash& get_root() const
259 {
260 return root;
261 }
262
263 std::shared_ptr<HistoryTree::Path> get_path()
264 {
265 return path;
266 }
267
268 Proof(HistoryTree* tree, uint64_t index)
269 {
270 root = tree->root();
271 path = tree->path(index);
272 }
273
274 Proof(const Proof&) = delete;
275
276 bool verify(HistoryTree* tree) const
277 {
278 if (path->max_index() > tree->max_index())
279 {
280 return false;
281 }
282 else if (tree->max_index() == path->max_index())
283 {
284 return tree->root() == root && path->verify(root);
285 }
286 else
287 {
288 auto past_root = tree->past_root(path->max_index());
289 return path->verify(*past_root);
290 }
291 }
292
293 std::vector<uint8_t> to_v() const
294 {
295 std::vector<uint8_t> v;
296 root.serialise(v);
297 path->serialise(v);
298 return v;
299 }
300 };
301
302 template <class T>
304 {
305 ccf::kv::TxID txid;
306 ccf::kv::Store& store;
307 ccf::kv::TxHistory& history;
308 NodeId id;
310 ccf::crypto::Pem& endorsed_cert;
311
312 public:
314 ccf::kv::TxID txid_,
315 ccf::kv::Store& store_,
316 ccf::kv::TxHistory& history_,
317 const NodeId& id_,
319 ccf::crypto::Pem& endorsed_cert_) :
320 txid(txid_),
321 store(store_),
322 history(history_),
323 id(id_),
324 kp(kp_),
325 endorsed_cert(endorsed_cert_)
326 {}
327
329 {
330 auto sig = store.create_reserved_tx(txid);
331 auto signatures =
332 sig.template wo<ccf::Signatures>(ccf::Tables::SIGNATURES);
333 auto serialised_tree = sig.template wo<ccf::SerialisedMerkleTree>(
334 ccf::Tables::SERIALISED_MERKLE_TREE);
336
337 std::vector<uint8_t> primary_sig;
338
339 primary_sig = kp.sign_hash(root.h.data(), root.h.size());
340
341 PrimarySignature sig_value(
342 id,
343 txid.version,
344 txid.term,
345 root,
346 {}, // Nonce is currently empty
347 primary_sig,
348 endorsed_cert);
349
350 signatures->put(sig_value);
351 serialised_tree->put(history.serialise_tree(txid.version - 1));
352 return sig.commit_reserved();
353 }
354 };
355
357 {
358 HistoryTree* tree;
359
360 public:
362
363 MerkleTreeHistory(const std::vector<uint8_t>& serialised)
364 {
365 tree = new HistoryTree(serialised);
366 }
367
369 {
370 tree = new HistoryTree(merkle::Hash(first_hash.h));
371 }
372
374 {
375 delete (tree);
376 tree = nullptr;
377 }
378
379 void deserialise(const std::vector<uint8_t>& serialised)
380 {
381 delete (tree);
382 tree = new HistoryTree(serialised);
383 }
384
386 {
387 tree->insert(merkle::Hash(hash.h));
388 }
389
391 {
392 const merkle::Hash& root = tree->root();
394 std::copy(root.bytes, root.bytes + root.size(), result.h.begin());
395 return result;
396 }
397
399 {
400 delete (tree);
402 tree = new HistoryTree(merkle::Hash(root.h));
403 }
404
405 void flush(uint64_t index)
406 {
407 LOG_TRACE_FMT("mt_flush_to index={}", index);
408 tree->flush_to(index);
409 }
410
411 void retract(uint64_t index)
412 {
413 LOG_TRACE_FMT("mt_retract_to index={}", index);
414 tree->retract_to(index);
415 }
416
417 Proof get_proof(uint64_t index)
418 {
419 if (index < begin_index())
420 {
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",
424 index,
425 begin_index()));
426 }
427 if (index > end_index())
428 {
429 throw std::logic_error(fmt::format(
430 "Cannot produce proof for {}: index is later than last index {}",
431 index,
432 end_index()));
433 }
434 return Proof(tree, index);
435 }
436
437 bool verify(const Proof& r)
438 {
439 return r.verify(tree);
440 }
441
442 std::vector<uint8_t> serialise()
443 {
444 LOG_TRACE_FMT("mt_serialize_size {}", tree->serialised_size());
445 std::vector<uint8_t> output;
446 tree->serialise(output);
447 return output;
448 }
449
450 std::vector<uint8_t> serialise(size_t from, size_t to)
451 {
453 "mt_serialize_size ({},{}) {}",
454 from,
455 to,
456 tree->serialised_size(from, to));
457 std::vector<uint8_t> output;
458 tree->serialise(from, to, output);
459 return output;
460 }
461
462 uint64_t begin_index()
463 {
464 return tree->min_index();
465 }
466
467 uint64_t end_index()
468 {
469 return tree->max_index();
470 }
471
472 bool in_range(uint64_t index)
473 {
474 return index >= begin_index() && index <= end_index();
475 }
476
478 {
479 const merkle::Hash& leaf = tree->leaf(index);
481 std::copy(leaf.bytes, leaf.bytes + leaf.size(), result.h.begin());
482 return result;
483 }
484 };
485
486 template <class T>
488 {
489 ccf::kv::Store& store;
490 NodeId id;
491 T replicated_state_tree;
492
495 std::vector<uint8_t> cose_cert_cached{};
496
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;
501
502 ccf::pal::Mutex state_lock;
503 ccf::kv::Term term_of_last_version = 0;
504 ccf::kv::Term term_of_next_version;
505
506 std::optional<ccf::crypto::Pem> endorsed_cert = std::nullopt;
507
508 public:
510 ccf::kv::Store& store_,
511 const NodeId& id_,
513 size_t sig_tx_interval_ = 0,
514 size_t sig_ms_interval_ = 0,
515 bool signature_timer = false) :
516 store(store_),
517 id(id_),
518 kp(kp_),
519 sig_tx_interval(sig_tx_interval_),
520 sig_ms_interval(sig_ms_interval_)
521 {
522 if (signature_timer)
523 {
525 }
526 }
527
529 {
530 struct EmitSigMsg
531 {
532 EmitSigMsg(HashedTxHistory<T>* self_) : self(self_) {}
533 HashedTxHistory<T>* self;
534 };
535
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;
539
540 std::unique_lock<ccf::pal::Mutex> mguard(
541 self->signature_lock, std::defer_lock);
542
543 bool should_emit_signature = false;
544
545 if (mguard.try_lock())
546 {
547 auto consensus = self->store.get_consensus();
548 if (consensus != nullptr)
549 {
550 auto sig_disp = consensus->get_signature_disposition();
551 switch (sig_disp)
552 {
554 {
555 break;
556 }
558 {
559 if (self->store.committable_gap() > 0)
560 {
561 should_emit_signature = true;
562 }
563 break;
564 }
566 {
567 should_emit_signature = true;
568 break;
569 }
570 }
571 }
572 }
573
574 if (should_emit_signature)
575 {
576 msg->data.self->emit_signature();
577 }
578
579 self->emit_signature_timer_entry =
581 std::move(msg), std::chrono::milliseconds(self->sig_ms_interval));
582 },
583 this);
584
585 emit_signature_timer_entry =
587 std::move(emit_sig_msg), std::chrono::milliseconds(sig_ms_interval));
588 }
589
591 {
592 if (emit_signature_timer_entry.has_value())
593 {
595 *emit_signature_timer_entry);
596 }
597 }
598
599 void set_node_id(const NodeId& id_)
600 {
601 id = id_;
602 }
603
605 const std::vector<uint8_t>& hash_at_snapshot) override
606 {
607 // The history can be initialised after a snapshot has been applied by
608 // deserialising the tree in the signatures table and then applying the
609 // hash of the transaction at which the snapshot was taken
610 auto tx = store.create_read_only_tx();
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())
615 {
616 LOG_FAIL_FMT("No tree found in serialised tree map");
617 return false;
618 }
619
620 // Delay taking this lock until _after_ the read above, to avoid lock
621 // inversions
622 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
623
625 !replicated_state_tree.in_range(1),
626 "Tree is not empty before initialising from snapshot");
627
628 replicated_state_tree.deserialise(tree.value());
629
631 std::copy_n(
632 hash_at_snapshot.begin(),
634 hash.h.begin());
635 replicated_state_tree.append(hash);
636 return true;
637 }
638
640 {
641 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
642 return replicated_state_tree.get_root();
643 }
644
645 std::tuple<ccf::kv::TxID, ccf::crypto::Sha256Hash, ccf::kv::Term>
647 {
648 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
649 return {
650 {term_of_last_version,
651 static_cast<ccf::kv::Version>(replicated_state_tree.end_index())},
652 replicated_state_tree.get_root(),
653 term_of_next_version};
654 }
655
656 bool verify_root_signatures(bool has_cose) override
657 {
658 auto tx = store.create_read_only_tx();
659
660 auto signatures =
661 tx.template ro<ccf::Signatures>(ccf::Tables::SIGNATURES);
662 auto sig = signatures->get();
663 if (!sig.has_value())
664 {
665 LOG_FAIL_FMT("No signature found in signatures map");
666 return false;
667 }
668
669 auto root = get_replicated_state_root();
670 log_hash(root, VERIFY);
671 if (!verify_node_signature(tx, sig->node, sig->sig, root))
672 {
673 return false;
674 }
675
676 if (!has_cose)
677 {
678 return true;
679 }
680
681 auto cose_signatures =
682 tx.template ro<ccf::CoseSignatures>(ccf::Tables::COSE_SIGNATURES);
683 auto cose_sig = cose_signatures->get();
684
685 if (!cose_sig.has_value())
686 {
687 return true;
688 }
689
690 auto service = tx.template ro<ccf::Service>(Tables::SERVICE);
691 auto service_info = service->get();
692
693 if (!service_info.has_value())
694 {
695 LOG_FAIL_FMT("No service key found to verify the signature");
696 return false;
697 }
698
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()};
702
703 return cose_verifier_cached(raw_cert)->verify_detached(
704 cose_sig.value(), root_hash);
705 }
706
707 std::vector<uint8_t> serialise_tree(size_t to) override
708 {
709 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
710 if (to <= replicated_state_tree.end_index())
711 {
712 return replicated_state_tree.serialise(
713 replicated_state_tree.begin_index(), to);
714 }
715 else
716 {
717 return {};
718 }
719 }
720
721 void set_term(ccf::kv::Term t) override
722 {
723 // This should only be called once, when the store first knows about its
724 // term
725 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
726 term_of_last_version = t;
727 term_of_next_version = t;
728 }
729
731 const ccf::kv::TxID& tx_id, ccf::kv::Term term_of_next_version_) override
732 {
733 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
734 LOG_TRACE_FMT("Rollback to {}.{}", tx_id.term, tx_id.version);
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);
739 }
740
741 void compact(ccf::kv::Version v) override
742 {
743 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
744 // Receipts can only be retrieved to the flushed index. Keep a range of
745 // history so that a range of receipts are available.
746 if (v > MAX_HISTORY_LEN)
747 {
748 replicated_state_tree.flush(v - MAX_HISTORY_LEN);
749 }
750 log_hash(replicated_state_tree.get_root(), COMPACT);
751 }
752
754
755 void try_emit_signature() override
756 {
757 std::unique_lock<ccf::pal::Mutex> mguard(signature_lock, std::defer_lock);
758 if (store.committable_gap() < sig_tx_interval || !mguard.try_lock())
759 {
760 return;
761 }
762
763 if (store.committable_gap() >= sig_tx_interval)
764 {
765 mguard.unlock();
767 }
768 }
769
770 void emit_signature() override
771 {
772 // Signatures are only emitted when there is a consensus
773 auto consensus = store.get_consensus();
774 if (!consensus)
775 {
776 return;
777 }
778
779 if (!endorsed_cert.has_value())
780 {
781 throw std::logic_error(
782 fmt::format("No endorsed certificate set to emit signature"));
783 }
784
785 auto txid = store.next_txid();
786
787 LOG_DEBUG_FMT("Signed at {} in view: {}", txid.version, txid.term);
788
789 store.commit(
790 txid,
791 std::make_unique<MerkleTreeHistoryPendingTx<T>>(
792 txid, store, *this, id, kp, endorsed_cert.value()),
793 true);
794 }
795
796 std::vector<uint8_t> get_proof(ccf::kv::Version index) override
797 {
798 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
799 return replicated_state_tree.get_proof(index).to_v();
800 }
801
802 bool verify_proof(const std::vector<uint8_t>& v) override
803 {
804 Proof proof(v);
805 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
806 return replicated_state_tree.verify(proof);
807 }
808
809 std::vector<uint8_t> get_raw_leaf(uint64_t index) override
810 {
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()};
814 }
815
816 void append(const std::vector<uint8_t>& data) override
817 {
819 log_hash(rh, APPEND);
820 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
821 replicated_state_tree.append(rh);
822 }
823
825 const ccf::crypto::Sha256Hash& digest,
826 std::optional<ccf::kv::Term> expected_term_of_next_version =
827 std::nullopt) override
828 {
829 log_hash(digest, APPEND);
830 std::lock_guard<ccf::pal::Mutex> guard(state_lock);
831 if (expected_term_of_next_version.has_value())
832 {
833 if (expected_term_of_next_version.value() != term_of_next_version)
834 {
835 return;
836 }
837 }
838 replicated_state_tree.append(digest);
839 }
840
842 {
843 endorsed_cert = cert;
844 }
845
846 private:
847 ccf::crypto::COSEVerifierUniquePtr& cose_verifier_cached(
848 const std::vector<uint8_t>& cert)
849 {
850 if (cert != cose_cert_cached)
851 {
852 cose_cert_cached = cert;
853 cose_verifier =
855 }
856 return cose_verifier;
857 }
858 };
859
861}
#define CCF_ASSERT_FMT(expr,...)
Definition ccf_assert.h:10
Definition history.h:488
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
Definition history.h:304
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
Definition history.h:357
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
Definition history.h:92
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
Definition history.h:120
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
Definition history.h:243
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
Definition key_pair.h:19
virtual std::vector< uint8_t > sign_hash(const uint8_t *hash, size_t hash_size) const =0
Definition pem.h:18
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
Definition store.h:87
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
Definition kv_types.h:50
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