CCF
Loading...
Searching...
No Matches
tx_id.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
5#include "ccf/ds/json.h"
6
7#include <charconv>
8#include <cstdint>
9#define FMT_HEADER_ONLY
10#include <fmt/format.h>
11#include <nlohmann/json.hpp>
12#include <optional>
13#include <string>
14#include <string_view>
15
16namespace ccf
17{
23 using View = uint64_t;
24
25 // No transactions occur in View 0.
26 constexpr View VIEW_UNKNOWN = 0;
27
36 using SeqNo = uint64_t;
37
38 // No transaction is assigned seqno 0.
39 constexpr SeqNo SEQNO_UNKNOWN = 0;
40
41 // The combination of View and SeqNo produce a unique TxID for each
42 // transaction executed by CCF.
43 struct TxID
44 {
47
48 std::string to_str() const
49 {
50 return std::to_string(view) + "." + std::to_string(seqno);
51 }
52
53 static std::optional<TxID> from_str(const std::string_view& sv)
54 {
55 const auto separator_idx = sv.find(".");
56 if (separator_idx == std::string_view::npos)
57 {
58 return std::nullopt;
59 }
60
61 TxID tx_id;
62
63 {
64 const auto view_sv = sv.substr(0, separator_idx);
65 const auto [p, ec] =
66 std::from_chars(view_sv.begin(), view_sv.end(), tx_id.view);
67 if (
68 ec != std::errc() || p != view_sv.end() || tx_id.view == VIEW_UNKNOWN)
69 {
70 return std::nullopt;
71 }
72 }
73
74 {
75 const auto seqno_sv = sv.substr(separator_idx + 1);
76 const auto [p, ec] =
77 std::from_chars(seqno_sv.begin(), seqno_sv.end(), tx_id.seqno);
78 if (
79 ec != std::errc() || p != seqno_sv.end() ||
80 tx_id.seqno == SEQNO_UNKNOWN)
81 {
82 return std::nullopt;
83 }
84 }
85
86 return tx_id;
87 }
88
89 bool operator==(const TxID& other) const
90 {
91 return view == other.view && seqno == other.seqno;
92 }
93 };
94
95 // ADL-found functions used during JSON conversion and OpenAPI/JSON schema
96 // generation
97 inline void to_json(nlohmann::json& j, const TxID& tx_id)
98 {
99 j = tx_id.to_str();
100 }
101
102 inline void from_json(const nlohmann::json& j, TxID& tx_id)
103 {
104 if (!j.is_string())
105 {
107 fmt::format("Cannot parse TxID: Expected string, got {}", j.dump()));
108 }
109
110 const auto opt = TxID::from_str(j.get<std::string>());
111 if (!opt.has_value())
112 {
113 throw ccf::JsonParseError(fmt::format("Cannot parse TxID: {}", j.dump()));
114 }
115
116 tx_id = opt.value();
117 }
118
119 inline std::string schema_name(const TxID*)
120 {
121 return "TransactionId";
122 }
123
124 inline void fill_json_schema(nlohmann::json& schema, const TxID*)
125 {
126 schema["type"] = "string";
127 schema["pattern"] = "^[0-9]+\\.[0-9]+$";
128 }
129}
Definition json.h:26
Definition app_interface.h:14
constexpr SeqNo SEQNO_UNKNOWN
Definition tx_id.h:39
void fill_json_schema(nlohmann::json &schema, const ClaimsDigest *)
Definition claims_digest.h:64
std::string schema_name(const ClaimsDigest *)
Definition claims_digest.h:59
void from_json(const nlohmann::json &j, ClaimsDigest &hash)
Definition claims_digest.h:54
constexpr View VIEW_UNKNOWN
Definition tx_id.h:26
uint64_t View
Definition tx_id.h:23
void to_json(nlohmann::json &j, const ClaimsDigest &hash)
Definition claims_digest.h:49
uint64_t SeqNo
Definition tx_id.h:36
Definition tx_id.h:44
SeqNo seqno
Definition tx_id.h:46
bool operator==(const TxID &other) const
Definition tx_id.h:89
View view
Definition tx_id.h:45
std::string to_str() const
Definition tx_id.h:48
static std::optional< TxID > from_str(const std::string_view &sv)
Definition tx_id.h:53