Consolidate View and SeqNo typedefs (#2367)

This commit is contained in:
Eddy Ashton 2021-03-30 13:13:12 +01:00 коммит произвёл GitHub
Родитель 70ceb39931
Коммит aa9e82279d
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
51 изменённых файлов: 681 добавлений и 619 удалений

Просмотреть файл

@ -444,7 +444,10 @@ if(BUILD_TESTS)
# Merkle Tree memory test
add_executable(merkle_mem src/node/test/merkle_mem.cpp)
target_link_libraries(merkle_mem PRIVATE ${CMAKE_THREAD_LIBS_INIT} crypto)
target_compile_options(merkle_mem PRIVATE ${COMPILE_LIBCXX})
target_link_libraries(
merkle_mem PRIVATE ${CMAKE_THREAD_LIBS_INIT} ${LINK_LIBCXX} crypto
)
# Raft driver and scenario test
add_executable(

Просмотреть файл

@ -65,6 +65,15 @@ Supporting Types
.. doxygenenum:: ccf::TxStatus
:project: CCF
.. doxygentypedef:: ccf::View
:project: CCF
.. doxygentypedef:: ccf::SeqNo
:project: CCF
.. doxygentypedef:: ccf::TxID
:project: CCF
.. doxygenenum:: ccf::ApiResult
:project: CCF

Просмотреть файл

@ -106,7 +106,7 @@
"GetNetworkInfo__Out": {
"properties": {
"current_view": {
"$ref": "#/components/schemas/int64"
"$ref": "#/components/schemas/uint64"
},
"primary_id": {
"$ref": "#/components/schemas/EntityId"
@ -188,16 +188,16 @@
"GetState__Out": {
"properties": {
"last_recovered_seqno": {
"$ref": "#/components/schemas/int64"
"$ref": "#/components/schemas/uint64"
},
"last_signed_seqno": {
"$ref": "#/components/schemas/int64"
"$ref": "#/components/schemas/uint64"
},
"node_id": {
"$ref": "#/components/schemas/EntityId"
},
"recovery_target_seqno": {
"$ref": "#/components/schemas/int64"
"$ref": "#/components/schemas/uint64"
},
"state": {
"$ref": "#/components/schemas/ccf__State"
@ -376,11 +376,6 @@
],
"type": "string"
},
"int64": {
"maximum": 9223372036854775807,
"minimum": -9223372036854775808,
"type": "integer"
},
"json": {},
"string": {
"type": "string"

Просмотреть файл

@ -88,14 +88,11 @@ namespace ccf
* @see ccf::TxStatus
*/
ApiResult get_status_for_txid_v1(
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
ccf::TxStatus& tx_status);
ccf::View view, ccf::SeqNo seqno, ccf::TxStatus& tx_status);
/** Get the ID of latest transaction known to be committed.
*/
ApiResult get_last_committed_txid_v1(
kv::Consensus::View& view, kv::Consensus::SeqNo& seqno);
ApiResult get_last_committed_txid_v1(ccf::View& view, ccf::SeqNo& seqno);
/** Generate an OpenAPI document describing the currently installed
* endpoints.
@ -120,7 +117,7 @@ namespace ccf
/** Get the view associated with a given seqno, to construct a valid TxID
*/
ApiResult get_view_for_seqno_v1(kv::SeqNo seqno, kv::Consensus::View& view);
ApiResult get_view_for_seqno_v1(ccf::SeqNo seqno, ccf::View& view);
/** Get the user data associated with a given user id
*/

Просмотреть файл

@ -9,7 +9,7 @@
namespace ccf::historical
{
using CheckAvailability = std::function<bool(
kv::Consensus::View view, kv::SeqNo seqno, std::string& error_reason)>;
ccf::View view, ccf::SeqNo seqno, std::string& error_reason)>;
using HandleHistoricalQuery =
std::function<void(ccf::endpoints::EndpointContext& args, StatePtr state)>;
@ -52,8 +52,8 @@ namespace ccf::historical
static inline bool is_tx_committed(
kv::Consensus* consensus,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
ccf::View view,
ccf::SeqNo seqno,
std::string& error_reason)
{
if (consensus == nullptr)

Просмотреть файл

@ -3,6 +3,7 @@
#pragma once
#include "ccf/receipt.h"
#include "ccf/tx_id.h"
#include "consensus/ledger_enclave_types.h"
#include "kv/store.h"
#include "node/history.h"
@ -63,12 +64,12 @@ namespace ccf::historical
/// Receipt for ledger entry at transaction_id
TxReceiptPtr receipt = nullptr;
/// View and Sequence Number for the State
kv::TxID transaction_id;
ccf::TxID transaction_id;
State(
const StorePtr& store_,
const TxReceiptPtr& receipt_,
const kv::TxID& transaction_id_) :
const ccf::TxID& transaction_id_) :
store(store_),
receipt(receipt_),
transaction_id(transaction_id_)
@ -119,18 +120,18 @@ namespace ccf::historical
*/
virtual StorePtr get_store_at(
RequestHandle handle,
kv::SeqNo seqno,
ccf::SeqNo seqno,
ExpiryDuration seconds_until_expiry) = 0;
/** Same as @c get_store_at but uses default expiry value.
* @see get_store_at
*/
virtual StorePtr get_store_at(RequestHandle handle, kv::SeqNo seqno) = 0;
virtual StorePtr get_store_at(RequestHandle handle, ccf::SeqNo seqno) = 0;
/** Retrieve a full state at a given seqno, including the Store, the TxID
* assigned by consensus, and an offline-verifiable receipt for the Tx.
*/
virtual StatePtr get_state_at(RequestHandle handle, kv::SeqNo seqno) = 0;
virtual StatePtr get_state_at(RequestHandle handle, ccf::SeqNo seqno) = 0;
/** Retrieve a range of Stores containing the state written at the given
* indices.
@ -152,15 +153,15 @@ namespace ccf::historical
*/
virtual std::vector<StorePtr> get_store_range(
RequestHandle handle,
kv::SeqNo start_seqno,
kv::SeqNo end_seqno,
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno,
ExpiryDuration seconds_until_expiry) = 0;
/** Same as @c get_store_range but uses default expiry value.
* @see get_store_range
*/
virtual std::vector<StorePtr> get_store_range(
RequestHandle handle, kv::SeqNo start_seqno, kv::SeqNo end_seqno) = 0;
RequestHandle handle, ccf::SeqNo start_seqno, ccf::SeqNo end_seqno) = 0;
/** Drop state for the given handle.
*

Просмотреть файл

@ -14,9 +14,31 @@
namespace ccf
{
/** Transactions occur within a fixed View. Each View generally spans a range
* of transactions, though empty Views are also possible. The View is advanced
* by the consensus protocol during election of a new leader, and a single
* leader is assigned in each View.
*/
using View = uint64_t;
// No transactions occur in View 0.
constexpr View VIEW_UNKNOWN = 0;
/** Each transaction is assigned a unique incrementing SeqNo, maintained
* across View transitions. This matches the order in which transactions are
* applied, where a higher SeqNo means that a transaction executed later.
* SeqNos are unique during normal operation, but around elections it is
* possible for distinct transactions in separate Views to have the same
* SeqNo. Only one of these transactions will ever commit, and the others are
* ephemeral.
*/
using SeqNo = uint64_t;
// No transaction is assigned seqno 0.
constexpr SeqNo SEQNO_UNKNOWN = 0;
// The combination of View and SeqNo produce a unique TxID for each
// transaction executed by CCF.
struct TxID
{
View view;

Просмотреть файл

@ -667,13 +667,11 @@ namespace loggingapp
}
};
auto is_tx_committed = [this](
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
std::string& error_reason) {
return ccf::historical::is_tx_committed(
consensus, view, seqno, error_reason);
};
auto is_tx_committed =
[this](ccf::View view, ccf::SeqNo seqno, std::string& error_reason) {
return ccf::historical::is_tx_committed(
consensus, view, seqno, error_reason);
};
make_endpoint(
"log/private/historical",
HTTP_GET,

Просмотреть файл

@ -19,8 +19,8 @@ namespace nobuiltins
std::vector<uint8_t> quote;
std::vector<uint8_t> endorsements;
kv::Consensus::View committed_view;
kv::Consensus::SeqNo committed_seqno;
ccf::View committed_view;
ccf::SeqNo committed_seqno;
};
DECLARE_JSON_TYPE(NodeSummary)
@ -119,8 +119,8 @@ namespace nobuiltins
.install();
auto get_commit = [this](auto&, nlohmann::json&&) {
kv::Consensus::View view;
kv::Consensus::SeqNo seqno;
ccf::View view;
ccf::SeqNo seqno;
const auto result = get_last_committed_txid_v1(view, seqno);
if (result == ccf::ApiResult::OK)
@ -159,7 +159,7 @@ namespace nobuiltins
nonstd::split_1(query_param, "=");
if (query_key == "seqno")
{
kv::SeqNo seqno;
ccf::SeqNo seqno;
const auto qv_begin = query_value.data();
const auto qv_end = qv_begin + query_value.size();
const auto [p, ec] = std::from_chars(qv_begin, qv_end, seqno);
@ -173,7 +173,7 @@ namespace nobuiltins
query_value));
}
kv::Consensus::View view;
ccf::View view;
const auto result = get_view_for_seqno_v1(seqno, view);
if (result == ccf::ApiResult::OK)
{

Просмотреть файл

@ -284,13 +284,11 @@ namespace ccfapp
info.has_value() &&
info.value().mode == ccf::endpoints::Mode::Historical)
{
auto is_tx_committed = [this](
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
std::string& error_reason) {
return ccf::historical::is_tx_committed(
consensus, view, seqno, error_reason);
};
auto is_tx_committed =
[this](ccf::View view, ccf::SeqNo seqno, std::string& error_reason) {
return ccf::historical::is_tx_committed(
consensus, view, seqno, error_reason);
};
ccf::historical::adapter(
[this, &method, &verb](
@ -315,7 +313,7 @@ namespace ccfapp
const ccf::RESTVerb& verb,
ccf::endpoints::EndpointContext& args,
kv::Tx& target_tx,
const std::optional<kv::TxID>& transaction_id,
const std::optional<ccf::TxID>& transaction_id,
ccf::historical::TxReceiptPtr receipt)
{
const auto local_method = method.substr(method.find_first_not_of('/'));

Просмотреть файл

@ -52,9 +52,9 @@ namespace aft
kv::Version ExecutorImpl::execute_request(
std::unique_ptr<RequestMessage> request,
bool is_create_request,
kv::Consensus::SeqNo prescribed_commit_version,
ccf::SeqNo prescribed_commit_version,
std::shared_ptr<aft::RequestTracker> request_tracker,
kv::Consensus::SeqNo max_conflict_version)
ccf::SeqNo max_conflict_version)
{
std::shared_ptr<enclave::RpcContext>& ctx = request->get_request_ctx().ctx;
std::shared_ptr<enclave::RpcHandler>& frontend =
@ -92,8 +92,7 @@ namespace aft
}
std::unique_ptr<aft::RequestMessage> ExecutorImpl::create_request_message(
const kv::TxHistory::RequestCallbackArgs& args,
kv::Consensus::SeqNo committed_seqno)
const kv::TxHistory::RequestCallbackArgs& args, ccf::SeqNo committed_seqno)
{
Request request = {
args.rid, args.caller_cert, args.request, args.frame_format};
@ -119,8 +118,8 @@ namespace aft
kv::Version ExecutorImpl::execute_request(
aft::Request& request,
std::shared_ptr<aft::RequestTracker> request_tracker,
kv::Consensus::SeqNo prescribed_commit_version,
kv::Consensus::SeqNo max_conflict_version)
ccf::SeqNo prescribed_commit_version,
ccf::SeqNo max_conflict_version)
{
auto ctx = create_request_ctx(request);

Просмотреть файл

@ -37,19 +37,19 @@ namespace aft
virtual kv::Version execute_request(
std::unique_ptr<RequestMessage> request,
bool is_create_request,
kv::Consensus::SeqNo prescribed_commit_version = kv::NoVersion,
ccf::SeqNo prescribed_commit_version = kv::NoVersion,
std::shared_ptr<aft::RequestTracker> request_tracker = nullptr,
kv::Consensus::SeqNo max_conflict_version = kv::NoVersion) = 0;
ccf::SeqNo max_conflict_version = kv::NoVersion) = 0;
virtual std::unique_ptr<aft::RequestMessage> create_request_message(
const kv::TxHistory::RequestCallbackArgs& args,
kv::Consensus::SeqNo committed_seqno) = 0;
ccf::SeqNo committed_seqno) = 0;
virtual kv::Version execute_request(
aft::Request& request,
std::shared_ptr<aft::RequestTracker> request_tracker,
kv::Consensus::SeqNo prescribed_commit_version,
kv::Consensus::SeqNo max_conflict_version) = 0;
ccf::SeqNo prescribed_commit_version,
ccf::SeqNo max_conflict_version) = 0;
};
class ExecutorImpl : public Executor
@ -72,19 +72,19 @@ namespace aft
kv::Version execute_request(
std::unique_ptr<RequestMessage> request,
bool is_create_request,
kv::Consensus::SeqNo prescribed_commit_version = kv::NoVersion,
ccf::SeqNo prescribed_commit_version = kv::NoVersion,
std::shared_ptr<aft::RequestTracker> request_tracker = nullptr,
kv::Consensus::SeqNo max_conflict_version = kv::NoVersion) override;
ccf::SeqNo max_conflict_version = kv::NoVersion) override;
std::unique_ptr<aft::RequestMessage> create_request_message(
const kv::TxHistory::RequestCallbackArgs& args,
kv::Consensus::SeqNo committed_seqno) override;
ccf::SeqNo committed_seqno) override;
kv::Version execute_request(
aft::Request& request,
std::shared_ptr<aft::RequestTracker> request_tracker,
kv::Consensus::SeqNo prescribed_commit_version,
kv::Consensus::SeqNo max_conflict_version) override;
ccf::SeqNo prescribed_commit_version,
ccf::SeqNo max_conflict_version) override;
private:
std::shared_ptr<State> state;

Просмотреть файл

@ -21,7 +21,7 @@ namespace aft
std::vector<kv::Version> views;
public:
static constexpr kv::Consensus::View InvalidView = ccf::VIEW_UNKNOWN;
static constexpr ccf::View InvalidView = ccf::VIEW_UNKNOWN;
void initialise(const std::vector<kv::Version>& terms_)
{
@ -33,7 +33,7 @@ namespace aft
LOG_DEBUG_FMT("Initialised views: {}", fmt::join(views, ", "));
}
void update(kv::Version idx, kv::Consensus::View view)
void update(kv::Version idx, ccf::View view)
{
LOG_DEBUG_FMT("Updating view to: {} at version: {}", view, idx);
if (!views.empty())
@ -48,14 +48,14 @@ namespace aft
}
}
for (int64_t i = views.size(); i < view; ++i)
for (ccf::View i = views.size(); i < view; ++i)
{
views.push_back(idx);
}
LOG_DEBUG_FMT("Resulting views: {}", fmt::join(views, ", "));
}
kv::Consensus::View view_at(kv::Version idx)
ccf::View view_at(kv::Version idx)
{
auto it = upper_bound(views.begin(), views.end(), idx);
@ -107,7 +107,7 @@ namespace aft
std::map<ccf::NodeId, std::shared_ptr<Replica>> configuration;
ccf::NodeId my_node_id;
kv::Consensus::View current_view;
ccf::View current_view;
kv::Version last_idx;
kv::Version commit_idx;

Просмотреть файл

@ -15,14 +15,14 @@ namespace aft
{
struct ViewChange
{
ViewChange(kv::Consensus::View view_, kv::Consensus::SeqNo seqno_) :
ViewChange(ccf::View view_, ccf::SeqNo seqno_) :
view(view_),
seqno(seqno_),
new_view_sent(false)
{}
kv::Consensus::View view;
kv::Consensus::SeqNo seqno;
ccf::View view;
ccf::SeqNo seqno;
bool new_view_sent;
std::map<ccf::NodeId, ccf::ViewChangeRequest> received_view_changes;
@ -55,12 +55,12 @@ namespace aft
(time_previous_view_change_increment != std::chrono::milliseconds(0));
}
kv::Consensus::View get_target_view() const
ccf::View get_target_view() const
{
return last_view_change_sent;
}
void set_current_view_change(kv::Consensus::View view)
void set_current_view_change(ccf::View view)
{
view_changes.clear();
last_view_change_sent = view;
@ -75,8 +75,8 @@ namespace aft
ResultAddView add_request_view_change(
ccf::ViewChangeRequest& v,
const ccf::NodeId& from,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
ccf::View view,
ccf::SeqNo seqno,
uint32_t node_count)
{
auto it = view_changes.find(view);
@ -101,16 +101,14 @@ namespace aft
return ResultAddView::OK;
}
kv::Consensus::SeqNo write_view_change_confirmation_append_entry(
kv::Consensus::View view)
ccf::SeqNo write_view_change_confirmation_append_entry(ccf::View view)
{
ccf::ViewChangeConfirmation nv =
create_view_change_confirmation_msg(view);
return store->write_view_change_confirmation(nv);
}
std::vector<uint8_t> get_serialized_view_change_confirmation(
kv::Consensus::View view)
std::vector<uint8_t> get_serialized_view_change_confirmation(ccf::View view)
{
ccf::ViewChangeConfirmation nv =
create_view_change_confirmation_msg(view);
@ -121,7 +119,7 @@ namespace aft
}
bool add_unknown_primary_evidence(
CBuffer data, kv::Consensus::View view, uint32_t node_count)
CBuffer data, ccf::View view, uint32_t node_count)
{
nlohmann::json j = nlohmann::json::parse(data.p);
auto vc = j.get<ccf::ViewChangeConfirmation>();
@ -150,12 +148,12 @@ namespace aft
return true;
}
bool check_evidence(kv::Consensus::View view) const
bool check_evidence(ccf::View view) const
{
return last_valid_view == view;
}
void clear(bool is_primary, kv::Consensus::View view)
void clear(bool is_primary, ccf::View view)
{
for (auto it = view_changes.begin(); it != view_changes.end();)
{
@ -174,15 +172,15 @@ namespace aft
private:
std::shared_ptr<ccf::ProgressTrackerStore> store;
std::map<kv::Consensus::View, ViewChange> view_changes;
std::map<ccf::View, ViewChange> view_changes;
std::chrono::milliseconds time_previous_view_change_increment =
std::chrono::milliseconds(0);
kv::Consensus::View last_view_change_sent = 0;
kv::Consensus::View last_valid_view = aft::starting_view_change;
ccf::View last_view_change_sent = 0;
ccf::View last_valid_view = aft::starting_view_change;
const std::chrono::milliseconds time_between_attempts;
ccf::ViewChangeConfirmation create_view_change_confirmation_msg(
kv::Consensus::View view)
ccf::View view)
{
auto it = view_changes.find(view);
if (it == view_changes.end())

Просмотреть файл

@ -281,7 +281,7 @@ namespace aft
return replica_state == Follower;
}
ccf::NodeId get_primary(kv::Consensus::View view)
ccf::NodeId get_primary(ccf::View view)
{
CCF_ASSERT_FMT(
consensus_type == ConsensusType::BFT,
@ -742,8 +742,8 @@ namespace aft
// We have not seen a request executed within an expected period of
// time. We should invoke a view-change.
//
kv::Consensus::View new_view = view_change_tracker->get_target_view();
kv::Consensus::SeqNo seqno;
ccf::View new_view = view_change_tracker->get_target_view();
ccf::SeqNo seqno;
std::unique_ptr<ccf::ViewChangeRequest> vc;
auto progress_tracker = store->get_progress_tracker();
@ -922,7 +922,7 @@ namespace aft
entries_batch_size = std::max((batch_window_sum / batch_window_size), 1);
}
void append_new_view(kv::Consensus::View view)
void append_new_view(ccf::View view)
{
state->current_view = view;
become_leader();
@ -936,7 +936,7 @@ namespace aft
bool has_bft_timeout_occurred(std::chrono::milliseconds time)
{
auto oldest_entry = request_tracker->oldest_entry();
kv::Consensus::SeqNo last_sig_seqno;
ccf::SeqNo last_sig_seqno;
std::chrono::milliseconds last_sig_time;
std::tie(last_sig_seqno, last_sig_time) =
request_tracker->get_seqno_time_last_request();
@ -1871,7 +1871,7 @@ namespace aft
try_send_sig_ack({r.term, r.last_log_idx}, result);
}
void try_send_sig_ack(kv::TxID tx_id, kv::TxHistory::Result r)
void try_send_sig_ack(ccf::TxID tx_id, kv::TxHistory::Result r)
{
switch (r)
{
@ -1883,7 +1883,7 @@ namespace aft
case kv::TxHistory::Result::SEND_SIG_RECEIPT_ACK:
{
SignaturesReceivedAck r = {
{bft_signature_received_ack}, tx_id.term, tx_id.version};
{bft_signature_received_ack}, tx_id.view, tx_id.seqno};
for (auto it = nodes.begin(); it != nodes.end(); ++it)
{
auto to = it->first;
@ -1936,7 +1936,7 @@ namespace aft
try_send_reply_and_nonce({r.term, r.idx}, result);
}
void try_send_reply_and_nonce(kv::TxID tx_id, kv::TxHistory::Result r)
void try_send_reply_and_nonce(ccf::TxID tx_id, kv::TxHistory::Result r)
{
switch (r)
{
@ -1953,7 +1953,7 @@ namespace aft
progress_tracker != nullptr, "progress_tracker is not set");
nonce = progress_tracker->get_node_nonce(tx_id);
NonceRevealMsg r = {
{bft_nonce_reveal}, tx_id.term, tx_id.version, nonce};
{bft_nonce_reveal}, tx_id.view, tx_id.seqno, nonce};
for (auto it = nodes.begin(); it != nodes.end(); ++it)
{

Просмотреть файл

@ -44,28 +44,28 @@ namespace aft
}
void force_become_primary(
SeqNo seqno,
View view,
ccf::SeqNo seqno,
ccf::View view,
const std::vector<kv::Version>& terms,
SeqNo commit_seqno) override
ccf::SeqNo commit_seqno) override
{
aft->force_become_leader(seqno, view, terms, commit_seqno);
}
void init_as_backup(
SeqNo seqno,
View view,
ccf::SeqNo seqno,
ccf::View view,
const std::vector<kv::Version>& view_history) override
{
aft->init_as_follower(seqno, view, view_history);
}
bool replicate(const kv::BatchVector& entries, View view) override
bool replicate(const kv::BatchVector& entries, ccf::View view) override
{
return aft->replicate(entries, view);
}
std::pair<View, SeqNo> get_committed_txid() override
std::pair<ccf::View, ccf::SeqNo> get_committed_txid() override
{
return aft->get_commit_term_and_idx();
}
@ -75,28 +75,28 @@ namespace aft
return aft->get_signable_commit_term_and_idx();
}
View get_view(SeqNo seqno) override
ccf::View get_view(ccf::SeqNo seqno) override
{
return aft->get_term(seqno);
}
View get_view() override
ccf::View get_view() override
{
return aft->get_term();
}
std::vector<SeqNo> get_view_history(SeqNo seqno) override
std::vector<ccf::SeqNo> get_view_history(ccf::SeqNo seqno) override
{
return aft->get_term_history(seqno);
}
void initialise_view_history(
const std::vector<SeqNo>& view_history) override
const std::vector<ccf::SeqNo>& view_history) override
{
aft->initialise_term_history(view_history);
}
SeqNo get_committed_seqno() override
ccf::SeqNo get_committed_seqno() override
{
return aft->get_commit_idx();
}
@ -122,7 +122,7 @@ namespace aft
}
void add_configuration(
SeqNo seqno, const Configuration::Nodes& conf) override
ccf::SeqNo seqno, const Configuration::Nodes& conf) override
{
aft->add_configuration(seqno, conf);
}

Просмотреть файл

@ -19,8 +19,8 @@
namespace aft
{
using Index = int64_t;
using Term = int64_t;
using Index = uint64_t;
using Term = uint64_t;
using Node2NodeMsg = uint64_t;
using Nonce = crypto::Sha256Hash;
@ -185,13 +185,13 @@ namespace aft
struct RequestViewChangeMsg : RaftHeader
{
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 0;
ccf::View view = 0;
ccf::SeqNo seqno = 0;
};
struct ViewChangeEvidenceMsg : RaftHeader
{
kv::Consensus::View view = 0;
ccf::View view = 0;
};
struct RequestVote : RaftHeader

Просмотреть файл

@ -29,12 +29,12 @@ namespace aft
struct RevealedNonces
{
kv::TxID tx_id;
ccf::TxID tx_id;
std::vector<RevealedNonce> nonces;
RevealedNonces() = default;
RevealedNonces(kv::TxID tx_id_) : tx_id(tx_id_) {}
RevealedNonces(ccf::TxID tx_id_) : tx_id(tx_id_) {}
};
DECLARE_JSON_TYPE(RevealedNonces);
DECLARE_JSON_REQUIRED_FIELDS(RevealedNonces, tx_id, nonces)

Просмотреть файл

@ -35,8 +35,8 @@ namespace consensus
struct AppendEntriesIndex
{
ccf::Index idx;
ccf::Index prev_idx;
ccf::SeqNo idx;
ccf::SeqNo prev_idx;
};
#pragma pack(pop)
}

Просмотреть файл

@ -7,20 +7,21 @@
namespace champ
{
using Version = int64_t;
using Version = uint64_t;
using DeletableVersion = int64_t;
template <typename V>
struct VersionV
{
Version version;
DeletableVersion version;
Version read_version;
V value;
VersionV() :
version(std::numeric_limits<Version>::min()),
read_version(std::numeric_limits<Version>::min())
version(std::numeric_limits<decltype(version)>::min()),
read_version(std::numeric_limits<decltype(read_version)>::min())
{}
VersionV(Version ver, Version read_ver, V val) :
VersionV(DeletableVersion ver, Version read_ver, V val) :
version(ver),
read_version(read_ver),
value(val)

Просмотреть файл

@ -43,12 +43,12 @@ namespace enclave
virtual ProcessBftResp process_bft(
std::shared_ptr<enclave::RpcContext> ctx,
kv::Consensus::SeqNo prescribed_commit_version,
kv::Consensus::SeqNo max_conflict_version) = 0;
ccf::SeqNo prescribed_commit_version,
ccf::SeqNo max_conflict_version) = 0;
virtual ProcessBftResp process_bft(
std::shared_ptr<enclave::RpcContext> ctx,
kv::Tx& tx,
kv::Consensus::SeqNo prescribed_commit_version = kv::NoVersion,
kv::Consensus::SeqNo max_conflict_version = kv::NoVersion) = 0;
ccf::SeqNo prescribed_commit_version = kv::NoVersion,
ccf::SeqNo max_conflict_version = kv::NoVersion) = 0;
};
}

Просмотреть файл

@ -15,9 +15,7 @@ namespace ccf
{}
ApiResult BaseEndpointRegistry::get_status_for_txid_v1(
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
ccf::TxStatus& tx_status)
ccf::View view, ccf::SeqNo seqno, ccf::TxStatus& tx_status)
{
try
{
@ -45,7 +43,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_last_committed_txid_v1(
kv::Consensus::View& view, kv::Consensus::SeqNo& seqno)
ccf::View& view, ccf::SeqNo& seqno)
{
if (consensus != nullptr)
{
@ -115,7 +113,7 @@ namespace ccf
}
ApiResult BaseEndpointRegistry::get_view_for_seqno_v1(
kv::SeqNo seqno, kv::Consensus::View& view)
ccf::SeqNo seqno, ccf::View& view)
{
try
{

Просмотреть файл

@ -65,8 +65,8 @@ namespace ccf
BaseEndpointRegistry::init_handlers();
auto get_commit = [this](auto&, nlohmann::json&&) {
kv::Consensus::View view;
kv::Consensus::SeqNo seqno;
ccf::View view;
ccf::SeqNo seqno;
const auto result = get_last_committed_txid_v1(view, seqno);
if (result == ccf::ApiResult::OK)
@ -223,35 +223,33 @@ namespace ccf
ccf::endpoints::ExecuteOutsideConsensus::Locally)
.install();
auto is_tx_committed = [this](
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
std::string& error_reason) {
if (consensus == nullptr)
{
error_reason = "Node is not fully configured";
return false;
}
auto is_tx_committed =
[this](ccf::View view, ccf::SeqNo seqno, std::string& error_reason) {
if (consensus == nullptr)
{
error_reason = "Node is not fully configured";
return false;
}
const auto tx_view = consensus->get_view(seqno);
const auto committed_seqno = consensus->get_committed_seqno();
const auto committed_view = consensus->get_view(committed_seqno);
const auto tx_view = consensus->get_view(seqno);
const auto committed_seqno = consensus->get_committed_seqno();
const auto committed_view = consensus->get_view(committed_seqno);
const auto tx_status = ccf::evaluate_tx_status(
view, seqno, tx_view, committed_view, committed_seqno);
if (tx_status != ccf::TxStatus::Committed)
{
error_reason = fmt::format(
"Only committed transactions can be queried. Transaction {}.{} is "
"{}",
view,
seqno,
ccf::tx_status_to_str(tx_status));
return false;
}
const auto tx_status = ccf::evaluate_tx_status(
view, seqno, tx_view, committed_view, committed_seqno);
if (tx_status != ccf::TxStatus::Committed)
{
error_reason = fmt::format(
"Only committed transactions can be queried. Transaction {}.{} is "
"{}",
view,
seqno,
ccf::tx_status_to_str(tx_status));
return false;
}
return true;
};
return true;
};
auto get_receipt =
[](auto& args, ccf::historical::StatePtr historical_state) {

Просмотреть файл

@ -65,7 +65,7 @@ namespace ws
static std::vector<uint8_t> make_out_frame(
size_t code,
kv::Version seqno,
kv::Consensus::View view,
ccf::View view,
const std::vector<uint8_t>& body)
{
size_t out_frame_size = ws::OUT_CCF_HEADER_SIZE + body.size();

Просмотреть файл

@ -16,7 +16,7 @@ namespace ws
size_t code,
const std::vector<uint8_t>& body,
kv::Version seqno = kv::NoVersion,
kv::Consensus::View view = ccf::VIEW_UNKNOWN)
ccf::View view = ccf::VIEW_UNKNOWN)
{
return make_out_frame(code, seqno, view, body);
};

Просмотреть файл

@ -483,7 +483,7 @@ namespace js
JSValue create_ccf_obj(
TxContext* txctx,
const std::optional<kv::TxID>& transaction_id,
const std::optional<ccf::TxID>& transaction_id,
ccf::historical::TxReceiptPtr receipt,
JSContext* ctx)
{
@ -530,13 +530,17 @@ namespace js
// Historical queries
if (receipt != nullptr)
{
CCF_ASSERT(
transaction_id.has_value(),
"Expected receipt and transaction_id to both be passed");
auto state = JS_NewObject(ctx);
ccf::TxID tx_id;
tx_id.seqno = static_cast<ccf::SeqNo>(transaction_id.value().version);
tx_id.view = static_cast<ccf::View>(transaction_id.value().term);
JS_SetPropertyStr(
ctx, state, "transactionId", JS_NewString(ctx, tx_id.to_str().c_str()));
ctx,
state,
"transactionId",
JS_NewString(ctx, transaction_id->to_str().c_str()));
ccf::Receipt receipt_out;
receipt->describe(receipt_out);
@ -580,7 +584,7 @@ namespace js
void populate_global_ccf(
TxContext* txctx,
const std::optional<kv::TxID>& transaction_id,
const std::optional<ccf::TxID>& transaction_id,
ccf::historical::TxReceiptPtr receipt,
JSContext* ctx)
{

Просмотреть файл

@ -43,7 +43,7 @@ namespace js
void populate_global_console(JSContext* ctx);
void populate_global_ccf(
TxContext* txctx,
const std::optional<kv::TxID>& transaction_id,
const std::optional<ccf::TxID>& transaction_id,
ccf::historical::TxReceiptPtr receipt,
JSContext* ctx);

Просмотреть файл

@ -21,7 +21,7 @@ namespace kv
// version of last transaction which read the key and committed successfully
using LastReadVersion = Version;
template <typename K>
using Read = std::map<K, std::tuple<Version, LastReadVersion>>;
using Read = std::map<K, std::tuple<DeletableVersion, LastReadVersion>>;
// nullopt values represent deletions
template <typename K, typename V>

Просмотреть файл

@ -328,7 +328,7 @@ namespace kv
return ApplyResult::FAIL;
}
kv::TxID tx_id;
ccf::TxID tx_id;
auto success = ApplyResult::PASS;
auto r = progress_tracker->receive_backup_signatures(
@ -350,8 +350,8 @@ namespace kv
return ApplyResult::FAIL;
}
term = tx_id.term;
version = tx_id.version;
term = tx_id.view;
version = tx_id.seqno;
history->append(data);
return success;

Просмотреть файл

@ -3,6 +3,7 @@
#pragma once
#include "ccf/entity_id.h"
#include "ccf/tx_id.h"
#include "crypto/hash.h"
#include "crypto/pem.h"
#include "ds/nonstd.h"
@ -31,12 +32,15 @@ namespace aft
namespace kv
{
// Version indexes modifications to the local kv store. Negative values
// indicate deletion
using Version = int64_t;
static const Version NoVersion = std::numeric_limits<Version>::min();
// Version indexes modifications to the local kv store.
using Version = uint64_t;
static constexpr Version NoVersion = 0u;
static bool is_deleted(Version version)
// DeletableVersion describes the version of an individual key within each
// table, which may be negative to indicate a deletion
using DeletableVersion = int64_t;
static bool is_deleted(DeletableVersion version)
{
return version < 0;
}
@ -45,21 +49,29 @@ namespace kv
// writer(s) changes. Term and Version combined give a unique identifier for
// all accepted kv modifications. Terms are handled by Consensus via the
// TermHistory
using Term = int64_t;
using Term = uint64_t;
using NodeId = ccf::NodeId;
struct TxID
{
Term term = 0;
Version version = 0;
TxID() = default;
TxID(Term t, Version v) : term(t), version(v) {}
// Would like to remove these duplicate types, but for now we just do free
// conversion
TxID(const ccf::TxID& other) : term(other.view), version(other.seqno) {}
operator ccf::TxID() const
{
return {term, version};
}
};
DECLARE_JSON_TYPE(TxID);
DECLARE_JSON_REQUIRED_FIELDS(TxID, term, version)
// SeqNo indexes transactions processed by the consensus protocol providing
// ordering
using SeqNo = int64_t;
struct Configuration
{
struct NodeInfo
@ -77,7 +89,7 @@ namespace kv
using Nodes = std::unordered_map<NodeId, NodeInfo>;
SeqNo idx;
ccf::SeqNo idx;
Nodes nodes;
};
@ -85,7 +97,7 @@ namespace kv
{
public:
virtual void add_configuration(
SeqNo seqno, const Configuration::Nodes& conf) = 0;
ccf::SeqNo seqno, const Configuration::Nodes& conf) = 0;
virtual Configuration::Nodes get_latest_configuration() = 0;
virtual Configuration::Nodes get_latest_configuration_unsafe() const = 0;
};
@ -285,11 +297,6 @@ namespace kv
NodeId local_id;
public:
using SeqNo = SeqNo;
// View describes an epoch of SeqNos. View is incremented when Consensus's
// primary changes
using View = int64_t;
Consensus(const NodeId& id) : state(Backup), local_id(id) {}
virtual ~Consensus() {}
@ -314,32 +321,33 @@ namespace kv
}
virtual void force_become_primary(
SeqNo, View, const std::vector<SeqNo>&, SeqNo)
ccf::SeqNo, ccf::View, const std::vector<ccf::SeqNo>&, ccf::SeqNo)
{
state = Primary;
}
virtual void init_as_backup(SeqNo, View, const std::vector<SeqNo>&)
virtual void init_as_backup(
ccf::SeqNo, ccf::View, const std::vector<ccf::SeqNo>&)
{
state = Backup;
}
virtual bool replicate(const BatchVector& entries, View view) = 0;
virtual std::pair<View, SeqNo> get_committed_txid() = 0;
virtual bool replicate(const BatchVector& entries, ccf::View view) = 0;
virtual std::pair<ccf::View, ccf::SeqNo> get_committed_txid() = 0;
struct SignableTxIndices
{
Term term;
SeqNo version, previous_version;
ccf::SeqNo version, previous_version;
};
virtual std::optional<SignableTxIndices> get_signable_txid() = 0;
virtual View get_view(SeqNo seqno) = 0;
virtual View get_view() = 0;
virtual std::vector<SeqNo> get_view_history(SeqNo) = 0;
virtual void initialise_view_history(const std::vector<SeqNo>&) = 0;
virtual SeqNo get_committed_seqno() = 0;
virtual ccf::View get_view(ccf::SeqNo seqno) = 0;
virtual ccf::View get_view() = 0;
virtual std::vector<ccf::SeqNo> get_view_history(ccf::SeqNo) = 0;
virtual void initialise_view_history(const std::vector<ccf::SeqNo>&) = 0;
virtual ccf::SeqNo get_committed_seqno() = 0;
virtual std::optional<NodeId> primary() = 0;
virtual bool view_change_in_progress() = 0;
virtual std::set<NodeId> active_nodes() = 0;

Просмотреть файл

@ -125,12 +125,16 @@ namespace kv
Version next_version_internal()
{
// Get the next global version. If the version becomes negative, wrap to
// 0.
// Get the next global version
++version;
if (version < 0)
// If the version becomes too large to represent in a DeletableVersion,
// wrap to 0
if (version > std::numeric_limits<DeletableVersion>::max())
{
LOG_FAIL_FMT("KV version too large - wrapping to 0");
version = 0;
}
return version;
}
@ -936,7 +940,7 @@ namespace kv
Version previous_last_replicated = 0;
Version next_last_replicated = 0;
Version previous_rollback_count = 0;
kv::Consensus::View replication_view = 0;
ccf::View replication_view = 0;
{
std::lock_guard<SpinLock> vguard(version_lock);

Просмотреть файл

@ -1471,169 +1471,202 @@ TEST_CASE("Conflict resolution")
REQUIRE_THROWS(tx2.commit());
}
TEST_CASE("Primary can create correct execution order")
std::string rand_string(size_t i)
{
struct TxInfo
{
uint32_t id;
kv::Version replicated_max_conflict_version;
};
std::vector<TxInfo> txs;
// Execute on primary
{
kv::Store kv_store_primary;
MapTypes::StringString map("public:map");
for (uint32_t i = 0; i < 5; ++i)
{
TxInfo info = {i, kv::NoVersion};
auto tx = kv_store_primary.create_tx();
auto handle = tx.rw(map);
handle->get(std::to_string(info.id));
handle->put(std::to_string(info.id), std::to_string(info.id));
REQUIRE(tx.commit(true) == kv::CommitResult::SUCCESS);
info.replicated_max_conflict_version = tx.get_max_conflict_version();
txs.push_back(info);
}
}
// Execute on backup
{
kv::Store kv_store_backup;
MapTypes::NumNum map("public:map");
// create the map on the backup
{
TxInfo& info = txs[0];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get(info.id);
handle->put(info.id, info.id);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.id, kv::NoVersion);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
// Verify that transactions can be execute in a random (reverse order) as
// there is no dependency
for (uint32_t i = 4; i > 0; --i)
{
TxInfo& info = txs[i];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get(info.id);
handle->put(info.id, info.id);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.id, 0);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
// Verify that the values can be read back
for (uint32_t i = 4; i > 1; --i)
{
TxInfo& info = txs[2];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
auto ret_value = handle->get(info.id);
REQUIRE(ret_value.has_value());
size_t value = ret_value.value();
REQUIRE(value == info.id);
}
}
return fmt::format("{}: {}", i, rand());
}
TEST_CASE("Backup can detect byzantine execution order")
TEST_CASE("Max conflict version tracks execution order")
{
struct TxInfo
{
uint32_t id;
std::string id;
std::string value;
kv::Version primary_committed_version;
kv::Version replicated_max_conflict_version;
};
std::vector<TxInfo> txs;
MapTypes::StringString map("public:map");
size_t tx_count = 5;
const auto fixed_key = rand_string(0);
// Execute on primary
for (bool dependencies_between_transactions : {false, true})
{
kv::Store kv_store_primary;
MapTypes::StringString map("public:map");
std::vector<TxInfo> txs;
for (uint32_t i = 0; i < 5; ++i)
// Execute on primary
{
TxInfo info = {i, 0};
auto tx = kv_store_primary.create_tx();
auto handle = tx.rw(map);
handle->get("key");
handle->put("key", std::to_string(info.id));
REQUIRE(tx.commit(true) == kv::CommitResult::SUCCESS);
txs.push_back(info);
}
}
// Execute on backup
{
kv::Store kv_store_backup;
MapTypes::StringString map("public:map");
// Run the transaction that creates the map
{
TxInfo& info = txs[0];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get("key");
handle->put("key", std::to_string(info.id));
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.id, kv::NoVersion);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
kv::Store kv_store_primary;
for (uint32_t i = 0; i < tx_count; ++i)
{
TxInfo info;
auto tx = kv_store_primary.create_tx();
auto handle = tx.rw(map);
if (!dependencies_between_transactions)
{
// Each transaction reads and writes independent keys - there is no
// dependency between transactions
info.id = rand_string(i);
info.value = rand_string(i);
REQUIRE(!handle->has(info.id));
}
else
{
// Each transaction reads the same key, and tries to write (at the
// same key) a value derived from the previous value
info.id = fixed_key;
const auto prev_value = handle->get(info.id);
info.value =
fmt::format("{} | {}", info.id, prev_value.value_or("NONE"));
}
handle->put(info.id, info.value);
REQUIRE(tx.commit(true) == kv::CommitResult::SUCCESS);
info.primary_committed_version = tx.commit_version();
info.replicated_max_conflict_version = tx.get_max_conflict_version();
txs.push_back(info);
}
}
// Run the transaction the final transaction so any transaction with a
// version before this one will result a linearlizability exception
{
TxInfo& info = txs[4];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get("key");
handle->put("key", std::to_string(info.id));
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.id, kv::NoVersion);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
REQUIRE(tx_count == txs.size());
// Validate the incorrectly created tx order cannot commit
for (uint32_t i = 1; i < 4; ++i)
// Execute on backup
{
TxInfo& info = txs[i];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->put("key", std::to_string(info.id));
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.id, kv::NoVersion);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::FAIL_CONFLICT);
kv::Store kv_store_backup;
kv::Version map_creation_version;
// create the map on the backup
{
TxInfo& info = txs[0];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
REQUIRE(!handle->has(info.id));
handle->put(info.id, info.value);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(info.primary_committed_version, kv::NoVersion);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
map_creation_version = tx.commit_version();
}
SUBCASE("Primary can construct correct execution order")
{
for (uint32_t i = 1; i < txs.size(); ++i)
{
TxInfo& info = txs[i];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
REQUIRE(!handle->has(info.id));
handle->put(info.id, info.value);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(
info.primary_committed_version, map_creation_version);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
// Verify that the values can be read back
for (const TxInfo& info : txs)
{
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
auto ret_value = handle->get(info.id);
REQUIRE(ret_value.has_value());
const auto value = ret_value.value();
REQUIRE(value == info.value);
}
}
SUBCASE("Byzantine execution order is refused by backup")
{
{
INFO(
"Reverse remaining transactions to produce different execution "
"order");
std::reverse(txs.begin() + 1, txs.end());
}
if (!dependencies_between_transactions)
{
// If there are no dependencies, the re-ordering doesn't matter -
// these transactions can still be executed successfully out-of-order
for (auto it = txs.begin() + 1; it != txs.end(); ++it)
{
TxInfo& info = *it;
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
REQUIRE(!handle->has(info.id));
handle->put(info.id, info.value);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(
info.primary_committed_version, map_creation_version);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
// Verify that the values can be read back
for (const TxInfo& info : txs)
{
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
auto ret_value = handle->get(info.id);
REQUIRE(ret_value.has_value());
const auto value = ret_value.value();
REQUIRE(value == info.value);
}
}
else
{
{
// Run the final transaction first, so any of the other transactions
// (whith a version before this one) will produce a
// linearilizability violation
TxInfo& info = txs[1];
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get(info.id);
handle->put(info.id, info.value);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(
info.primary_committed_version, map_creation_version);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::SUCCESS);
}
// Validate the incorrectly created tx order cannot commit
for (auto it = txs.begin() + 2; it != txs.end(); ++it)
{
TxInfo& info = *it;
auto tx = kv_store_backup.create_tx();
auto handle = tx.rw(map);
handle->get(info.id);
handle->put(info.id, info.value);
auto version_resolver = [&](bool) {
kv_store_backup.next_version();
return std::make_tuple(
info.primary_committed_version, map_creation_version);
};
REQUIRE(
tx.commit(
true, version_resolver, info.replicated_max_conflict_version) ==
kv::CommitResult::FAIL_CONFLICT);
}
}
}
}
}
}

Просмотреть файл

@ -31,7 +31,7 @@ namespace kv::test
consensus_type(consensus_type_)
{}
bool replicate(const BatchVector& entries, View view) override
bool replicate(const BatchVector& entries, ccf::View view) override
{
for (const auto& entry : entries)
{
@ -79,7 +79,7 @@ namespace kv::test
replica.clear();
}
std::pair<View, SeqNo> get_committed_txid() override
std::pair<ccf::View, ccf::SeqNo> get_committed_txid() override
{
return {2, 0};
}
@ -94,7 +94,7 @@ namespace kv::test
return r;
}
SeqNo get_committed_seqno() override
ccf::SeqNo get_committed_seqno() override
{
return 0;
}
@ -119,23 +119,23 @@ namespace kv::test
return PrimaryNodeId;
}
View get_view(SeqNo seqno) override
ccf::View get_view(ccf::SeqNo seqno) override
{
return 2;
}
View get_view() override
ccf::View get_view() override
{
return 2;
}
std::vector<SeqNo> get_view_history(SeqNo seqno) override
std::vector<ccf::SeqNo> get_view_history(ccf::SeqNo seqno) override
{
return view_history.get_history_until(seqno);
}
void initialise_view_history(
const std::vector<SeqNo>& view_history_) override
const std::vector<ccf::SeqNo>& view_history_) override
{
view_history.initialise(view_history_);
}
@ -143,7 +143,7 @@ namespace kv::test
void recv_message(const NodeId& from, OArray&& oa) override {}
void add_configuration(
SeqNo seqno, const Configuration::Nodes& conf) override
ccf::SeqNo seqno, const Configuration::Nodes& conf) override
{}
Configuration::Nodes get_latest_configuration_unsafe() const override
@ -184,7 +184,7 @@ namespace kv::test
return false;
}
bool replicate(const BatchVector& entries, View view) override
bool replicate(const BatchVector& entries, ccf::View view) override
{
return false;
}

Просмотреть файл

@ -66,7 +66,15 @@ namespace kv
bool committed = false;
bool success = false;
Version read_version = NoVersion;
// In most places we use NoVersion to indicate an invalid version. In this
// case, NoVersion is a valid value - it is the version that the first
// transaction in the service will read from, before anything has been
// applied to the KV. So we need an additional special value to distinguish
// "haven't yet fetched a read_version" from "have fetched a read_version,
// and it is NoVersion", and we get that by wrapping this in a
// std::optional with nullopt representing "not yet fetched".
std::optional<Version> read_version = std::nullopt;
Version version = NoVersion;
Version max_conflict_version = NoVersion;
Term term = 0;
@ -117,7 +125,7 @@ namespace kv
throw CompactedVersionConflict(fmt::format(
"Unable to retrieve state over map {} at {}",
map_name,
read_version));
read_version.value()));
}
auto typed_handle = get_or_insert_handle<THandle>(*change_set, map_name);
@ -136,7 +144,7 @@ namespace kv
return handle;
}
if (read_version == NoVersion)
if (!read_version.has_value())
{
// Grab opacity version that all Maps should be queried at.
auto txid = store->current_txid();
@ -144,7 +152,7 @@ namespace kv
read_version = txid.version;
}
auto abstract_map = store->get_map(read_version, map_name);
auto abstract_map = store->get_map(read_version.value(), map_name);
if (abstract_map == nullptr)
{
// Store doesn't know this map yet - create it dynamically
@ -178,7 +186,7 @@ namespace kv
fmt::format("Map {} has unexpected type", map_name));
}
auto change_set = untyped_map->create_change_set(read_version);
auto change_set = untyped_map->create_change_set(read_version.value());
return check_and_store_change_set<THandle>(
std::move(change_set), map_name, abstract_map);
}
@ -229,7 +237,7 @@ namespace kv
Version get_read_version()
{
return read_version;
return read_version.value_or(NoVersion);
}
Version get_max_conflict_version()
@ -244,7 +252,7 @@ namespace kv
void set_read_version_and_term(Version v, Term t)
{
if (read_version == NoVersion)
if (!read_version.has_value())
{
read_version = v;
term = t;
@ -494,7 +502,7 @@ namespace kv
created_maps.clear();
committed = false;
success = false;
read_version = NoVersion;
read_version = std::nullopt;
version = NoVersion;
term = 0;
root_at_read_version = std::nullopt;

Просмотреть файл

@ -127,8 +127,9 @@ namespace kv::untyped
auto search = state.get(it->first);
if (search.has_value())
{
max_conflict_version =
std::max(max_conflict_version, search->version);
max_conflict_version = std::max(
max_conflict_version,
static_cast<kv::Version>(abs(search->version)));
}
else
{
@ -195,8 +196,9 @@ namespace kv::untyped
{
if (search.has_value() && max_conflict_version != kv::NoVersion)
{
max_conflict_version =
std::max(max_conflict_version, search->version);
max_conflict_version = std::max(
max_conflict_version,
static_cast<kv::Version>(abs(search->version)));
}
else
{
@ -214,8 +216,9 @@ namespace kv::untyped
auto search = current->state.get(it->first);
if (search.has_value() && max_conflict_version != kv::NoVersion)
{
max_conflict_version =
std::max(max_conflict_version, search->version);
max_conflict_version = std::max(
max_conflict_version,
static_cast<kv::Version>(abs(search->version)));
max_conflict_version =
std::max(max_conflict_version, search->read_version);
}
@ -233,7 +236,7 @@ namespace kv::untyped
return true;
}
void commit(Version v, bool track_read_versions) override
void commit(Version v_, bool track_read_versions) override
{
if (change_set.writes.empty() && !track_read_versions)
{
@ -244,6 +247,8 @@ namespace kv::untyped
auto& roll = map.get_roll();
auto state = roll.commits->get_tail()->state;
DeletableVersion v = static_cast<DeletableVersion>(v_);
// To track conflicts the read version of all keys that are read or
// written within a transaction must be updated.
if (track_read_versions)
@ -256,8 +261,8 @@ namespace kv::untyped
{
continue;
}
state =
state.put(it->first, VersionV{search->version, v, search->value});
state = state.put(
it->first, VersionV{search->version, v_, search->value});
}
if (change_set.writes.empty())
{
@ -279,7 +284,7 @@ namespace kv::untyped
{
// Write the new value with the global version.
changes = true;
state = state.put(it->first, VersionV{v, v, it->second.value()});
state = state.put(it->first, VersionV{v, v_, it->second.value()});
}
else
{
@ -289,7 +294,7 @@ namespace kv::untyped
if (search.has_value())
{
changes = true;
state = state.put(it->first, VersionV{-v, -v, {}});
state = state.put(it->first, VersionV{-v, v_, {}});
}
}
}

Просмотреть файл

@ -12,17 +12,15 @@ namespace ccf
{
struct BackupSignatures
{
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 0;
ccf::View view = 0;
ccf::SeqNo seqno = 0;
crypto::Sha256Hash root;
std::vector<NodeSignature> signatures;
BackupSignatures() = default;
BackupSignatures(
kv::Consensus::View view_,
kv::Consensus::SeqNo seqno_,
const crypto::Sha256Hash root_) :
ccf::View view_, ccf::SeqNo seqno_, const crypto::Sha256Hash root_) :
view(view_),
seqno(seqno_),
root(root_)

Просмотреть файл

@ -20,13 +20,13 @@
namespace ccf
{
using SeqNo = uint64_t;
using GcmHdr = crypto::GcmHeader<sizeof(SeqNo)>;
using SendNonce = uint64_t;
using GcmHdr = crypto::GcmHeader<sizeof(SendNonce)>;
struct RecvNonce
{
uint8_t tid;
uint64_t nonce : (sizeof(uint64_t) - sizeof(uint8_t)) * CHAR_BIT;
uint64_t nonce : (sizeof(SendNonce) - sizeof(tid)) * CHAR_BIT;
RecvNonce(uint64_t nonce_, uint8_t tid_) : tid(tid_), nonce(nonce_) {}
RecvNonce(const uint64_t header)
@ -40,7 +40,7 @@ namespace ccf
}
};
static_assert(
sizeof(RecvNonce) == sizeof(SeqNo), "RecvNonce is the wrong size");
sizeof(RecvNonce) == sizeof(SendNonce), "RecvNonce is the wrong size");
static inline RecvNonce get_nonce(const GcmHdr& header)
{
@ -111,7 +111,7 @@ namespace ccf
std::unique_ptr<crypto::KeyAesGcm> next_key;
// Incremented for each tagged/encrypted message
std::atomic<SeqNo> send_nonce{1};
std::atomic<SendNonce> send_nonce{1};
// Used to buffer at most one message sent on the channel before it is
// established
@ -121,8 +121,8 @@ namespace ccf
// Set to the latest successfully received nonce.
struct ChannelSeqno
{
SeqNo main_thread_seqno;
SeqNo tid_seqno;
SendNonce main_thread_seqno;
SendNonce tid_seqno;
};
std::array<ChannelSeqno, threading::ThreadMessaging::max_num_threads>
local_recv_nonce = {{}};
@ -147,7 +147,7 @@ namespace ccf
current_tid == threading::ThreadMessaging::main_thread ||
current_tid % threading::ThreadMessaging::thread_count == tid);
SeqNo* local_nonce;
SendNonce* local_nonce;
if (current_tid == threading::ThreadMessaging::main_thread)
{
local_nonce = &local_recv_nonce[tid].main_thread_seqno;

Просмотреть файл

@ -12,7 +12,6 @@
namespace ccf
{
using Index = int64_t;
using Node2NodeMsg = uint64_t;
using Cert = std::vector<uint8_t>;

Просмотреть файл

@ -56,11 +56,11 @@ namespace ccf::historical
struct LedgerSecretRecoveryInfo
{
kv::SeqNo target_seqno = 0;
ccf::SeqNo target_seqno = 0;
LedgerSecretPtr last_ledger_secret;
LedgerSecretRecoveryInfo(
kv::SeqNo target_seqno_, LedgerSecretPtr last_ledger_secret_) :
ccf::SeqNo target_seqno_, LedgerSecretPtr last_ledger_secret_) :
target_seqno(target_seqno_),
last_ledger_secret(last_ledger_secret_)
{}
@ -89,21 +89,22 @@ namespace ccf::historical
StorePtr store = nullptr;
bool is_signature = false;
TxReceiptPtr receipt = nullptr;
kv::TxID transaction_id;
ccf::TxID transaction_id;
};
using StoreDetailsPtr = std::shared_ptr<StoreDetails>;
struct Request
{
kv::SeqNo first_requested_seqno = 0;
kv::SeqNo last_requested_seqno = 0;
ccf::SeqNo first_requested_seqno = 0;
ccf::SeqNo last_requested_seqno = 0;
std::vector<StoreDetailsPtr> requested_stores;
std::chrono::milliseconds time_to_expiry;
// Entries from outside the requested range (such as the next signature)
// may be needed to trust this range. They are stored here, distinct from
// user-requested stores.
std::optional<std::pair<kv::SeqNo, StoreDetailsPtr>> supporting_signature;
std::optional<std::pair<ccf::SeqNo, StoreDetailsPtr>>
supporting_signature;
// Only set when recovering ledger secrets
std::unique_ptr<LedgerSecretRecoveryInfo> ledger_secret_recovery_info =
@ -111,7 +112,7 @@ namespace ccf::historical
Request() {}
StoreDetailsPtr get_store_details(kv::SeqNo seqno) const
StoreDetailsPtr get_store_details(ccf::SeqNo seqno) const
{
if (seqno >= first_requested_seqno && seqno <= last_requested_seqno)
{
@ -143,8 +144,8 @@ namespace ccf::historical
// adjust to:
// 0 1 2 3 4 5 6
// we need to shift _and_ start fetching 0, 1, and 6.
std::set<kv::SeqNo> adjust_range(
kv::SeqNo start_seqno, size_t num_following_indices)
std::set<ccf::SeqNo> adjust_range(
ccf::SeqNo start_seqno, size_t num_following_indices)
{
if (
start_seqno == first_requested_seqno &&
@ -154,10 +155,10 @@ namespace ccf::historical
return {};
}
std::set<kv::SeqNo> ret;
std::set<ccf::SeqNo> ret;
std::vector<StoreDetailsPtr> new_stores(num_following_indices + 1);
for (auto seqno = start_seqno; seqno <=
static_cast<kv::SeqNo>(start_seqno + num_following_indices);
static_cast<ccf::SeqNo>(start_seqno + num_following_indices);
++seqno)
{
auto existing_details = get_store_details(seqno);
@ -216,7 +217,7 @@ namespace ccf::historical
Invalidated,
};
UpdateTrustedResult update_trusted(kv::SeqNo new_seqno)
UpdateTrustedResult update_trusted(ccf::SeqNo new_seqno)
{
auto new_details = get_store_details(new_seqno);
if (new_details->is_signature)
@ -355,11 +356,11 @@ namespace ccf::historical
// Track all things currently requested by external callers
std::map<RequestHandle, Request> requests;
std::set<kv::SeqNo> pending_fetches;
std::set<ccf::SeqNo> pending_fetches;
ExpiryDuration default_expiry_duration = std::chrono::seconds(1800);
void fetch_entry_at(kv::SeqNo seqno)
void fetch_entry_at(ccf::SeqNo seqno)
{
const auto ib = pending_fetches.insert(seqno);
if (ib.second)
@ -386,7 +387,7 @@ namespace ccf::historical
// Returns true if this is a valid signature that passes our verification
// checks
bool verify_signature(const StorePtr& sig_store, kv::SeqNo sig_seqno)
bool verify_signature(const StorePtr& sig_store, ccf::SeqNo sig_seqno)
{
const auto sig = get_signature(sig_store);
if (!sig.has_value())
@ -432,7 +433,7 @@ namespace ccf::historical
}
std::unique_ptr<LedgerSecretRecoveryInfo> fetch_supporting_secret_if_needed(
kv::SeqNo seqno)
ccf::SeqNo seqno)
{
auto [earliest_ledger_secret_seqno, earliest_ledger_secret] =
get_earliest_known_ledger_secret();
@ -467,7 +468,7 @@ namespace ccf::historical
void process_deserialised_store(
const StorePtr& store,
const crypto::Sha256Hash& entry_digest,
kv::SeqNo seqno,
ccf::SeqNo seqno,
bool is_signature)
{
auto request_it = requests.begin();
@ -607,7 +608,7 @@ namespace ccf::historical
std::vector<StatePtr> get_store_range_internal(
RequestHandle handle,
kv::SeqNo start_seqno,
ccf::SeqNo start_seqno,
size_t num_following_indices,
ExpiryDuration seconds_until_expiry)
{
@ -662,8 +663,8 @@ namespace ccf::historical
std::vector<StatePtr> trusted_states;
for (kv::SeqNo seqno = start_seqno;
seqno <= static_cast<kv::SeqNo>(start_seqno + num_following_indices);
for (ccf::SeqNo seqno = start_seqno; seqno <=
static_cast<ccf::SeqNo>(start_seqno + num_following_indices);
++seqno)
{
auto target_details = request.get_store_details(seqno);
@ -690,7 +691,7 @@ namespace ccf::historical
// Used when we received an invalid entry, to drop any requests which were
// asking for it
void delete_all_interested_requests(kv::SeqNo seqno)
void delete_all_interested_requests(ccf::SeqNo seqno)
{
auto request_it = requests.begin();
while (request_it != requests.end())
@ -721,7 +722,7 @@ namespace ccf::historical
StorePtr get_store_at(
RequestHandle handle,
kv::SeqNo seqno,
ccf::SeqNo seqno,
ExpiryDuration seconds_until_expiry) override
{
auto range = get_store_range(handle, seqno, seqno, seconds_until_expiry);
@ -733,12 +734,12 @@ namespace ccf::historical
return range[0];
}
StorePtr get_store_at(RequestHandle handle, kv::SeqNo seqno) override
StorePtr get_store_at(RequestHandle handle, ccf::SeqNo seqno) override
{
return get_store_at(handle, seqno, default_expiry_duration);
}
StatePtr get_state_at(RequestHandle handle, kv::SeqNo seqno) override
StatePtr get_state_at(RequestHandle handle, ccf::SeqNo seqno) override
{
auto range =
get_store_range_internal(handle, seqno, 1, default_expiry_duration);
@ -753,8 +754,8 @@ namespace ccf::historical
std::vector<StorePtr> get_store_range(
RequestHandle handle,
kv::SeqNo start_seqno,
kv::SeqNo end_seqno,
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno,
ExpiryDuration seconds_until_expiry) override
{
if (end_seqno < start_seqno)
@ -777,7 +778,9 @@ namespace ccf::historical
}
std::vector<StorePtr> get_store_range(
RequestHandle handle, kv::SeqNo start_seqno, kv::SeqNo end_seqno) override
RequestHandle handle,
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno) override
{
return get_store_range(
handle, start_seqno, end_seqno, default_expiry_duration);
@ -795,7 +798,7 @@ namespace ccf::historical
return erased_count > 0;
}
bool handle_ledger_entry(kv::SeqNo seqno, const LedgerEntry& data)
bool handle_ledger_entry(ccf::SeqNo seqno, const LedgerEntry& data)
{
std::lock_guard<SpinLock> guard(requests_lock);
const auto it = pending_fetches.find(seqno);
@ -883,7 +886,7 @@ namespace ccf::historical
return true;
}
void handle_no_entry(kv::SeqNo seqno)
void handle_no_entry(ccf::SeqNo seqno)
{
std::lock_guard<SpinLock> guard(requests_lock);

Просмотреть файл

@ -30,7 +30,7 @@ namespace ccf
std::shared_ptr<ProgressTrackerStore> store;
kv::TxHistory::Result add_signature(
kv::TxID tx_id,
ccf::TxID tx_id,
const NodeId& node_id,
uint32_t signature_size,
std::array<uint8_t, MBEDTLS_ECDSA_MAX_LEN>& sig,
@ -50,7 +50,7 @@ namespace ccf
}
kv::TxHistory::Result record_primary(
kv::TxID tx_id,
ccf::TxID tx_id,
NodeId node_id,
crypto::Sha256Hash& root,
std::vector<uint8_t>& sig,
@ -69,12 +69,12 @@ namespace ccf
LOG_TRACE_FMT(
"record_primary node_id:{}, seqno:{}, hashed_nonce:{}, root:{}, sig:{}",
node_id,
tx_id.version,
tx_id.seqno,
hashed_nonce,
root,
sig);
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
CommitCert cert(root, my_nonce);
@ -82,15 +82,15 @@ namespace ccf
BftNodeSignature bft_node_sig(sig, node_id, hashed_nonce);
bft_node_sig.is_primary = true;
try_match_unmatched_nonces(
cert, bft_node_sig, tx_id.term, tx_id.version, node_id);
cert, bft_node_sig, tx_id.view, tx_id.seqno, node_id);
cert.sigs.insert(
std::pair<NodeId, BftNodeSignature>(node_id, bft_node_sig));
certificates.insert(
std::pair<kv::Consensus::SeqNo, CommitCert>(tx_id.version, cert));
std::pair<ccf::SeqNo, CommitCert>(tx_id.seqno, cert));
LOG_TRACE_FMT(
"Adding new root for view:{}, seqno:{}", tx_id.term, tx_id.version);
"Adding new root for view:{}, seqno:{}", tx_id.view, tx_id.seqno);
return kv::TxHistory::Result::OK;
}
else
@ -102,7 +102,7 @@ namespace ccf
BftNodeSignature bft_node_sig({}, node_id, hashed_nonce);
bft_node_sig.is_primary = true;
try_match_unmatched_nonces(
cert, bft_node_sig, tx_id.term, tx_id.version, node_id);
cert, bft_node_sig, tx_id.view, tx_id.seqno, node_id);
cert.my_nonce = my_nonce;
cert.have_primary_signature = true;
for (auto& sig : cert.sigs)
@ -121,14 +121,14 @@ namespace ccf
"record_primary: Signature verification from {} FAILED, view:{}, "
"seqno:{}",
sig.first,
tx_id.term,
tx_id.version));
tx_id.view,
tx_id.seqno));
}
LOG_TRACE_FMT(
"Signature verification from {} passed, view:{}, seqno:{}",
sig.second.node,
tx_id.term,
tx_id.version);
tx_id.view,
tx_id.seqno);
}
cert.sigs.insert(
std::pair<NodeId, BftNodeSignature>(node_id, bft_node_sig));
@ -150,16 +150,16 @@ namespace ccf
}
kv::TxHistory::Result record_primary_signature(
kv::TxID tx_id, std::vector<uint8_t>& sig)
ccf::TxID tx_id, std::vector<uint8_t>& sig)
{
std::unique_lock<SpinLock> guard(lock);
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
LOG_FAIL_FMT(
"Adding signature to primary that does not exist view:{}, seqno:{}",
tx_id.term,
tx_id.version);
tx_id.view,
tx_id.seqno);
return kv::TxHistory::Result::FAIL;
}
@ -178,7 +178,7 @@ namespace ccf
}
kv::TxHistory::Result receive_backup_signatures(
kv::TxID& tx_id, uint32_t node_count, bool is_primary)
ccf::TxID& tx_id, uint32_t node_count, bool is_primary)
{
std::unique_lock<SpinLock> guard(lock);
std::optional<ccf::BackupSignatures> sigs =
@ -256,8 +256,8 @@ namespace ccf
}
}
tx_id.term = sigs_value.view;
tx_id.version = sigs_value.seqno;
tx_id.view = sigs_value.view;
tx_id.seqno = sigs_value.seqno;
return success;
}
@ -269,14 +269,14 @@ namespace ccf
CCF_ASSERT(nonces.has_value(), "nonces does not have a value");
aft::RevealedNonces& nonces_value = nonces.value();
auto it = certificates.find(nonces_value.tx_id.version);
auto it = certificates.find(nonces_value.tx_id.seqno);
if (it == certificates.end())
{
LOG_FAIL_FMT(
"Primary send backup signatures before sending the primary "
"signature view:{}, seqno:{}",
nonces_value.tx_id.term,
nonces_value.tx_id.version);
nonces_value.tx_id.view,
nonces_value.tx_id.seqno);
return kv::TxHistory::Result::FAIL;
}
@ -290,8 +290,8 @@ namespace ccf
"Node {} sent revealed nonce before sending a signature view:{}, "
"seqno:{}",
revealed_nonce.node_id,
nonces_value.tx_id.term,
nonces_value.tx_id.version);
nonces_value.tx_id.view,
nonces_value.tx_id.seqno);
return kv::TxHistory::Result::FAIL;
}
@ -302,8 +302,8 @@ namespace ccf
LOG_FAIL_FMT(
"Hashed nonces does not match with nonce view:{}, seqno:{}, "
"node_id:{}",
nonces_value.tx_id.term,
nonces_value.tx_id.version,
nonces_value.tx_id.view,
nonces_value.tx_id.seqno,
revealed_nonce.node_id);
return kv::TxHistory::Result::FAIL;
}
@ -315,31 +315,30 @@ namespace ccf
}
cert.nonces_committed_to_ledger = true;
try_update_watermark(cert, nonces_value.tx_id.version, true);
try_update_watermark(cert, nonces_value.tx_id.seqno, true);
return kv::TxHistory::Result::OK;
}
kv::TxHistory::Result add_signature_ack(
kv::TxID tx_id, const NodeId& node_id, uint32_t node_count = 0)
ccf::TxID tx_id, const NodeId& node_id, uint32_t node_count = 0)
{
std::unique_lock<SpinLock> guard(lock);
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
// We currently do not know what the root is, so lets save this
// signature and and we will verify the root when we get it from the
// primary
auto r =
certificates.insert(std::pair<kv::Consensus::SeqNo, CommitCert>(
tx_id.version, CommitCert()));
auto r = certificates.insert(
std::pair<ccf::SeqNo, CommitCert>(tx_id.seqno, CommitCert()));
it = r.first;
}
LOG_TRACE_FMT(
"processing recv_signature_received_ack, from:{} view:{}, seqno:{}",
node_id,
tx_id.term,
tx_id.version);
tx_id.view,
tx_id.seqno);
auto& cert = it->second;
cert.sig_acks.insert(node_id);
@ -352,7 +351,7 @@ namespace ccf
}
void add_nonce_reveal(
kv::TxID tx_id,
ccf::TxID tx_id,
Nonce nonce,
const NodeId& node_id,
uint32_t node_count,
@ -360,15 +359,14 @@ namespace ccf
{
std::unique_lock<SpinLock> guard(lock);
bool did_add = false;
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
// We currently do not know what the root is, so lets save this
// signature and and we will verify the root when we get it from the
// primary
auto r =
certificates.insert(std::pair<kv::Consensus::SeqNo, CommitCert>(
tx_id.version, CommitCert()));
auto r = certificates.insert(
std::pair<ccf::SeqNo, CommitCert>(tx_id.seqno, CommitCert()));
it = r.first;
did_add = true;
}
@ -385,8 +383,8 @@ namespace ccf
LOG_TRACE_FMT(
"add_nonce_reveal view:{}, seqno:{}, node_id:{}, sig.hashed_nonce:{}, "
" received.nonce:{}, hash(received.nonce):{} did_add:{}",
tx_id.term,
tx_id.version,
tx_id.view,
tx_id.seqno,
node_id,
sig.hashed_nonce,
nonce,
@ -401,8 +399,8 @@ namespace ccf
"Nonces do not match add_nonce_reveal view:{}, seqno:{}, node_id:{}, "
"sig.hashed_nonce:{}, "
" received.nonce:{}, hash(received.nonce):{} did_add:{}",
tx_id.term,
tx_id.version,
tx_id.view,
tx_id.seqno,
node_id,
sig.hashed_nonce,
nonce,
@ -411,8 +409,8 @@ namespace ccf
throw ccf::ccf_logic_error(fmt::format(
"nonces do not match verification from {} FAILED, view:{}, seqno:{}",
node_id,
tx_id.term,
tx_id.version));
tx_id.view,
tx_id.seqno));
}
sig.nonce = nonce;
cert.nonce_set.insert(node_id);
@ -435,16 +433,16 @@ namespace ccf
store->write_nonces(revealed_nonces);
}
try_update_watermark(cert, tx_id.version, is_primary);
try_update_watermark(cert, tx_id.seqno, is_primary);
}
crypto::Sha256Hash get_node_hashed_nonce(kv::TxID tx_id)
crypto::Sha256Hash get_node_hashed_nonce(ccf::TxID tx_id)
{
std::unique_lock<SpinLock> guard(lock);
return get_node_hashed_nonce_internal(tx_id);
}
void get_node_hashed_nonce(kv::TxID tx_id, crypto::Sha256Hash& hash)
void get_node_hashed_nonce(ccf::TxID tx_id, crypto::Sha256Hash& hash)
{
Nonce nonce = get_node_nonce(tx_id);
hash_data(nonce, hash);
@ -467,22 +465,22 @@ namespace ccf
hash = crypto::Sha256Hash({data.h.data(), data.h.size()});
}
kv::Consensus::SeqNo get_highest_committed_nonce()
ccf::SeqNo get_highest_committed_nonce()
{
return highest_commit_level;
}
std::tuple<std::unique_ptr<ViewChangeRequest>, kv::Consensus::SeqNo>
get_view_change_message(kv::Consensus::View view)
std::tuple<std::unique_ptr<ViewChangeRequest>, ccf::SeqNo>
get_view_change_message(ccf::View view)
{
std::unique_lock<SpinLock> guard(lock);
auto it = certificates.find(highest_prepared_level.version);
auto it = certificates.find(highest_prepared_level.seqno);
if (it == certificates.end())
{
throw ccf::ccf_logic_error(fmt::format(
"Invalid prepared level, view:{}, seqno:{}",
highest_prepared_level.term,
highest_prepared_level.version));
highest_prepared_level.view,
highest_prepared_level.seqno));
}
auto& cert = it->second;
@ -493,15 +491,15 @@ namespace ccf
m->signatures.push_back(sig.second);
}
store->sign_view_change_request(*m, view, highest_prepared_level.version);
return std::make_tuple(std::move(m), highest_prepared_level.version);
store->sign_view_change_request(*m, view, highest_prepared_level.seqno);
return std::make_tuple(std::move(m), highest_prepared_level.seqno);
}
bool apply_view_change_message(
ViewChangeRequest& view_change,
const NodeId& from,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno)
ccf::View view,
ccf::SeqNo seqno)
{
std::unique_lock<SpinLock> guard(lock);
if (!store->verify_view_change_request(view_change, from, view, seqno))
@ -559,25 +557,25 @@ namespace ccf
bool apply_new_view(
const NodeId& from,
uint32_t node_count,
kv::Consensus::View& view_,
kv::Consensus::SeqNo& seqno_) const
ccf::View& view_,
ccf::SeqNo& seqno_) const
{
std::unique_lock<SpinLock> guard(lock);
auto new_view = store->get_new_view();
CCF_ASSERT(new_view.has_value(), "new view does not have a value");
kv::Consensus::View view = new_view->view;
kv::Consensus::SeqNo seqno = new_view->seqno;
ccf::View view = new_view->view;
ccf::SeqNo seqno = new_view->seqno;
if (
seqno < highest_prepared_level.version ||
view < highest_prepared_level.term)
seqno < highest_prepared_level.seqno ||
view < highest_prepared_level.view)
{
LOG_FAIL_FMT(
"Invalid view and seqno in the new view highest prepared from:{}, "
"view:{},seqno:{}, new_view view:{}, seqno:{}",
from,
highest_prepared_level.term,
highest_prepared_level.version,
highest_prepared_level.view,
highest_prepared_level.seqno,
view,
seqno);
return false;
@ -625,7 +623,7 @@ namespace ccf
return true;
}
Nonce get_node_nonce(kv::TxID tx_id)
Nonce get_node_nonce(ccf::TxID tx_id)
{
std::unique_lock<SpinLock> guard(lock);
return get_node_nonce_(tx_id);
@ -634,14 +632,14 @@ namespace ccf
private:
NodeId id;
std::shared_ptr<crypto::Entropy> entropy;
kv::Consensus::SeqNo highest_commit_level = 0;
kv::TxID highest_prepared_level = {0, 0};
ccf::SeqNo highest_commit_level = 0;
ccf::TxID highest_prepared_level = {0, 0};
std::map<kv::Consensus::SeqNo, CommitCert> certificates;
std::map<ccf::SeqNo, CommitCert> certificates;
mutable SpinLock lock;
kv::TxHistory::Result add_signature_internal(
kv::TxID tx_id,
ccf::TxID tx_id,
const NodeId& node_id,
uint32_t signature_size,
std::array<uint8_t, MBEDTLS_ECDSA_MAX_LEN>& sig,
@ -652,17 +650,16 @@ namespace ccf
LOG_TRACE_FMT(
"add_signature node_id:{}, seqno:{}, hashed_nonce:{}",
node_id,
tx_id.version,
tx_id.seqno,
hashed_nonce);
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
// At this point the appropriate Merkle root is not known. The signature
// will be recorded and verified when the primary sends the apporiate
// Merkle root.
auto r =
certificates.insert(std::pair<kv::Consensus::SeqNo, CommitCert>(
tx_id.version, CommitCert()));
auto r = certificates.insert(
std::pair<ccf::SeqNo, CommitCert>(tx_id.seqno, CommitCert()));
it = r.first;
}
else
@ -676,15 +673,15 @@ namespace ccf
"add_signatures: Signature verification from {} FAILED, view:{}, "
"seqno:{}",
node_id,
tx_id.term,
tx_id.version));
tx_id.view,
tx_id.seqno));
return kv::TxHistory::Result::FAIL;
}
LOG_TRACE_FMT(
"Signature verification from {} passed, view:{}, seqno:{}",
node_id,
tx_id.term,
tx_id.version);
tx_id.view,
tx_id.seqno);
}
auto& cert = it->second;
@ -692,8 +689,8 @@ namespace ccf
{
LOG_TRACE_FMT(
"Already wrote append entry view:{}, seqno:{}, ignoring",
tx_id.term,
tx_id.version);
tx_id.view,
tx_id.seqno);
return kv::TxHistory::Result::OK;
}
@ -715,7 +712,7 @@ namespace ccf
BftNodeSignature bft_node_sig(std::move(sig_vec), node_id, hashed_nonce);
try_match_unmatched_nonces(
cert, bft_node_sig, tx_id.term, tx_id.version, node_id);
cert, bft_node_sig, tx_id.view, tx_id.seqno, node_id);
cert.sigs.insert(
std::pair<NodeId, BftNodeSignature>(node_id, std::move(bft_node_sig)));
@ -723,7 +720,7 @@ namespace ccf
{
if (is_primary)
{
ccf::BackupSignatures sig_value(tx_id.term, tx_id.version, cert.root);
ccf::BackupSignatures sig_value(tx_id.view, tx_id.seqno, cert.root);
for (const auto& sig : cert.sigs)
{
@ -734,7 +731,7 @@ namespace ccf
}
}
LOG_TRACE_FMT("Adding signatures to ledger seqno:{}", tx_id.version);
LOG_TRACE_FMT("Adding signatures to ledger seqno:{}", tx_id.seqno);
store->write_backup_signatures(sig_value);
cert.wrote_sig_to_ledger = true;
}
@ -743,20 +740,20 @@ namespace ccf
return kv::TxHistory::Result::OK;
}
Nonce get_node_nonce_(kv::TxID tx_id)
Nonce get_node_nonce_(ccf::TxID tx_id)
{
auto it = certificates.find(tx_id.version);
auto it = certificates.find(tx_id.seqno);
if (it == certificates.end())
{
throw ccf::ccf_logic_error(fmt::format(
"Attempting to access unknown nonce, view:{}, seqno:{}",
tx_id.term,
tx_id.version));
tx_id.view,
tx_id.seqno));
}
return it->second.my_nonce;
}
crypto::Sha256Hash get_node_hashed_nonce_internal(kv::TxID tx_id)
crypto::Sha256Hash get_node_hashed_nonce_internal(ccf::TxID tx_id)
{
Nonce nonce = get_node_nonce_(tx_id);
return hash_data(nonce);
@ -765,8 +762,8 @@ namespace ccf
void try_match_unmatched_nonces(
CommitCert& cert,
BftNodeSignature& bft_node_sig,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno,
ccf::View view,
ccf::SeqNo seqno,
const NodeId& node_id)
{
auto it_unmatched_nonces = cert.unmatched_nonces.find(node_id);
@ -813,19 +810,19 @@ namespace ccf
}
bool can_send_sig_ack(
CommitCert& cert, const kv::TxID& tx_id, uint32_t node_count)
CommitCert& cert, const ccf::TxID& tx_id, uint32_t node_count)
{
if (
cert.sigs.size() >= get_message_threshold(node_count) &&
!cert.ack_sent && cert.have_primary_signature)
{
if (tx_id.version > highest_prepared_level.version)
if (tx_id.seqno > highest_prepared_level.seqno)
{
CCF_ASSERT_FMT(
tx_id.term >= highest_prepared_level.term,
tx_id.view >= highest_prepared_level.view,
"Prepared terms are moving backwards new_term:{}, current_term:{}",
tx_id.term,
highest_prepared_level.term);
tx_id.view,
highest_prepared_level.view);
highest_prepared_level = tx_id;
}
@ -848,9 +845,7 @@ namespace ccf
}
void try_update_watermark(
CommitCert& cert,
kv::Consensus::SeqNo seqno,
bool should_clear_old_entries)
CommitCert& cert, ccf::SeqNo seqno, bool should_clear_old_entries)
{
if (cert.nonces_committed_to_ledger && seqno > highest_commit_level)
{

Просмотреть файл

@ -70,15 +70,13 @@ namespace ccf
uint32_t sig_size,
uint8_t* sig) = 0;
virtual void sign_view_change_request(
ViewChangeRequest& view_change,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno) = 0;
ViewChangeRequest& view_change, ccf::View view, ccf::SeqNo seqno) = 0;
virtual bool verify_view_change_request(
ViewChangeRequest& view_change,
const NodeId& from,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno) = 0;
virtual kv::Consensus::SeqNo write_view_change_confirmation(
ccf::View view,
ccf::SeqNo seqno) = 0;
virtual ccf::SeqNo write_view_change_confirmation(
ViewChangeConfirmation& new_view) = 0;
virtual bool verify_view_change_request_confirmation(
ViewChangeConfirmation& new_view, const NodeId& from) = 0;
@ -148,12 +146,12 @@ namespace ccf
{
LOG_FAIL_FMT(
"Failed to write nonces, view:{}, seqno:{}",
nonces.tx_id.term,
nonces.tx_id.version);
nonces.tx_id.view,
nonces.tx_id.seqno);
throw ccf_logic_error(fmt::format(
"Failed to write nonces, view:{}, seqno:{}",
nonces.tx_id.term,
nonces.tx_id.version));
nonces.tx_id.view,
nonces.tx_id.seqno));
}
}
@ -192,9 +190,7 @@ namespace ccf
}
void sign_view_change_request(
ViewChangeRequest& view_change,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno) override
ViewChangeRequest& view_change, ccf::View view, ccf::SeqNo seqno) override
{
crypto::Sha256Hash h = hash_view_change(view_change, view, seqno);
view_change.signature = kp.sign_hash(h.h.data(), h.h.size());
@ -203,8 +199,8 @@ namespace ccf
bool verify_view_change_request(
ViewChangeRequest& view_change,
const NodeId& from,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno) override
ccf::View view,
ccf::SeqNo seqno) override
{
crypto::Sha256Hash h = hash_view_change(view_change, view, seqno);
@ -240,7 +236,7 @@ namespace ccf
h.h, new_view.signature, crypto::MDType::SHA256);
}
kv::Consensus::SeqNo write_view_change_confirmation(
ccf::SeqNo write_view_change_confirmation(
ViewChangeConfirmation& new_view) override
{
kv::Tx tx(&store);
@ -290,9 +286,7 @@ namespace ccf
NewViewsMap new_views;
crypto::Sha256Hash hash_view_change(
const ViewChangeRequest& v,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno) const
const ViewChangeRequest& v, ccf::View view, ccf::SeqNo seqno) const
{
auto ch = crypto::make_incremental_sha256();

Просмотреть файл

@ -123,8 +123,7 @@ namespace aft
hashes_without_requests_list.is_empty();
}
void insert_signed_request(
kv::Consensus::SeqNo seqno, std::chrono::milliseconds time)
void insert_signed_request(ccf::SeqNo seqno, std::chrono::milliseconds time)
{
std::unique_lock<SpinLock> guard(lock);
if (seqno > seqno_last_signature)
@ -134,7 +133,7 @@ namespace aft
}
}
std::tuple<kv::Consensus::SeqNo, std::chrono::milliseconds>
std::tuple<ccf::SeqNo, std::chrono::milliseconds>
get_seqno_time_last_request() const
{
std::unique_lock<SpinLock> guard(lock);
@ -159,7 +158,7 @@ namespace aft
snmalloc::DLList<Request, std::nullptr_t, true>
hashes_without_requests_list;
kv::Consensus::SeqNo seqno_last_signature = -1;
ccf::SeqNo seqno_last_signature = ccf::SEQNO_UNKNOWN;
std::chrono::milliseconds time_last_signature =
std::chrono::milliseconds(0);
mutable SpinLock lock;

Просмотреть файл

@ -54,7 +54,7 @@ namespace ccf
struct Out
{
ServiceStatus service_status;
std::optional<kv::Consensus::View> current_view;
std::optional<ccf::View> current_view;
std::optional<NodeId> primary_id;
};
};

Просмотреть файл

@ -151,7 +151,7 @@ namespace ccf
kv::Tx& tx,
const PreExec& pre_exec = {},
kv::Version prescribed_commit_version = kv::NoVersion,
kv::Consensus::SeqNo max_conflict_version = kv::NoVersion)
ccf::SeqNo max_conflict_version = kv::NoVersion)
{
const auto endpoint = endpoints.find_endpoint(tx, *ctx);
if (endpoint == nullptr)
@ -584,8 +584,8 @@ namespace ccf
ProcessBftResp process_bft(
std::shared_ptr<enclave::RpcContext> ctx,
kv::Consensus::SeqNo prescribed_commit_version,
kv::Consensus::SeqNo max_conflict_version) override
ccf::SeqNo prescribed_commit_version,
ccf::SeqNo max_conflict_version) override
{
auto tx = tables.create_tx();
return process_bft(
@ -602,8 +602,8 @@ namespace ccf
ProcessBftResp process_bft(
std::shared_ptr<enclave::RpcContext> ctx,
kv::Tx& tx,
kv::Consensus::SeqNo prescribed_commit_version = kv::NoVersion,
kv::Consensus::SeqNo max_conflict_version = kv::NoVersion) override
ccf::SeqNo prescribed_commit_version = kv::NoVersion,
ccf::SeqNo max_conflict_version = kv::NoVersion) override
{
// Note: this can only happen if the primary is malicious,
// and has executed a user transaction when the service wasn't

Просмотреть файл

@ -100,28 +100,28 @@ namespace ccf
historical::StorePtr get_store_at(
historical::RequestHandle handle,
kv::SeqNo seqno,
ccf::SeqNo seqno,
historical::ExpiryDuration seconds_until_expiry)
{
return nullptr;
}
historical::StorePtr get_store_at(
historical::RequestHandle handle, kv::SeqNo seqno)
historical::RequestHandle handle, ccf::SeqNo seqno)
{
return nullptr;
}
historical::StatePtr get_state_at(
historical::RequestHandle handle, kv::SeqNo seqno)
historical::RequestHandle handle, ccf::SeqNo seqno)
{
return nullptr;
}
std::vector<historical::StorePtr> get_store_range(
historical::RequestHandle handle,
kv::SeqNo start_seqno,
kv::SeqNo end_seqno,
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno,
historical::ExpiryDuration seconds_until_expiry)
{
return {};
@ -129,8 +129,8 @@ namespace ccf
std::vector<historical::StorePtr> get_store_range(
historical::RequestHandle handle,
kv::SeqNo start_seqno,
kv::SeqNo end_seqno)
ccf::SeqNo start_seqno,
ccf::SeqNo end_seqno)
{
return {};
}

Просмотреть файл

@ -2,6 +2,7 @@
// Licensed under the Apache 2.0 License.
#pragma once
#include "ccf/tx_id.h"
#include "ds/json.h"
namespace ccf
@ -64,14 +65,12 @@ namespace ccf
{TxStatus::Committed, tx_status_to_str(TxStatus::Committed)},
{TxStatus::Invalid, tx_status_to_str(TxStatus::Invalid)}});
constexpr int64_t VIEW_UNKNOWN = std::numeric_limits<int64_t>::min();
inline TxStatus evaluate_tx_status(
int64_t target_view,
int64_t target_seqno,
int64_t local_view,
int64_t committed_view,
int64_t committed_seqno)
[[maybe_unused]] static TxStatus evaluate_tx_status(
View target_view,
SeqNo target_seqno,
View local_view,
View committed_view,
SeqNo committed_seqno)
{
const bool is_committed = committed_seqno >= target_seqno;
const bool views_match = local_view == target_view;

Просмотреть файл

@ -12,15 +12,15 @@ namespace ccf
{
struct PrimarySignature : public NodeSignature
{
kv::Consensus::SeqNo seqno = 0;
kv::Consensus::View view = 0;
kv::Consensus::SeqNo commit_seqno = 0;
kv::Consensus::View commit_view = 0;
ccf::SeqNo seqno = 0;
ccf::View view = 0;
ccf::SeqNo commit_seqno = 0;
ccf::View commit_view = 0;
crypto::Sha256Hash root;
PrimarySignature() {}
PrimarySignature(const ccf::NodeId& node_, kv::Consensus::SeqNo seqno_) :
PrimarySignature(const ccf::NodeId& node_, ccf::SeqNo seqno_) :
NodeSignature(node_),
seqno(seqno_)
{}
@ -29,10 +29,10 @@ namespace ccf
PrimarySignature(
const ccf::NodeId& node_,
kv::Consensus::SeqNo seqno_,
kv::Consensus::View view_,
kv::Consensus::SeqNo commit_seqno_,
kv::Consensus::View commit_view_,
ccf::SeqNo seqno_,
ccf::View view_,
ccf::SeqNo commit_seqno_,
ccf::View commit_view_,
const crypto::Sha256Hash root_,
Nonce hashed_nonce_,
const std::vector<uint8_t>& sig_) :

Просмотреть файл

@ -195,7 +195,7 @@ kv::Version rekey(
}
void validate_business_transaction(
ccf::historical::StorePtr store, kv::SeqNo seqno)
ccf::historical::StorePtr store, ccf::SeqNo seqno)
{
REQUIRE(store != nullptr);
@ -227,14 +227,14 @@ void validate_business_transaction(
});
}
std::map<kv::SeqNo, std::vector<uint8_t>> construct_host_ledger(
std::map<ccf::SeqNo, std::vector<uint8_t>> construct_host_ledger(
std::shared_ptr<kv::Consensus> c)
{
auto consensus = dynamic_cast<kv::test::StubConsensus*>(c.get());
REQUIRE(consensus != nullptr);
INFO("Rebuild ledger as seen by host");
std::map<kv::SeqNo, std::vector<uint8_t>> ledger;
std::map<ccf::SeqNo, std::vector<uint8_t>> ledger;
auto next_ledger_entry = consensus->pop_oldest_entry();
while (next_ledger_entry.has_value())
@ -296,8 +296,8 @@ TEST_CASE("StateCache point queries")
{
INFO("The host sees requests for these indices");
REQUIRE(!stub_writer->writes.empty());
std::set<kv::SeqNo> expected{low_seqno, high_seqno, unsigned_seqno};
std::set<kv::SeqNo> actual;
std::set<ccf::SeqNo> expected{low_seqno, high_seqno, unsigned_seqno};
std::set<ccf::SeqNo> actual;
for (const auto& write : stub_writer->writes)
{
const uint8_t* data = write.contents.data();

Просмотреть файл

@ -26,7 +26,7 @@ public:
DummyConsensus(kv::Store* store_) : store(store_) {}
bool replicate(const kv::BatchVector& entries, View view) override
bool replicate(const kv::BatchVector& entries, ccf::View view) override
{
if (store)
{
@ -37,12 +37,12 @@ public:
return true;
}
std::pair<View, SeqNo> get_committed_txid() override
std::pair<ccf::View, ccf::SeqNo> get_committed_txid() override
{
return {2, 0};
}
SeqNo get_committed_seqno() override
ccf::SeqNo get_committed_seqno() override
{
return 0;
}
@ -215,7 +215,7 @@ public:
CompactingConsensus(kv::Store* store_) : store(store_) {}
bool replicate(const kv::BatchVector& entries, View view) override
bool replicate(const kv::BatchVector& entries, ccf::View view) override
{
for (auto& [version, data, committable, hooks] : entries)
{
@ -226,12 +226,12 @@ public:
return true;
}
std::pair<View, SeqNo> get_committed_txid() override
std::pair<ccf::View, ccf::SeqNo> get_committed_txid() override
{
return {2, 0};
}
SeqNo get_committed_seqno() override
ccf::SeqNo get_committed_seqno() override
{
return 0;
}
@ -246,7 +246,7 @@ public:
return kv::test::PrimaryNodeId;
}
View get_view(kv::Version version) override
ccf::View get_view(kv::Version version) override
{
return 2;
}
@ -254,12 +254,12 @@ public:
class TestPendingTx : public kv::PendingTx
{
kv::TxID txid;
ccf::TxID txid;
kv::Store& store;
MapT& other_table;
public:
TestPendingTx(kv::TxID txid_, kv::Store& store_, MapT& other_table_) :
TestPendingTx(ccf::TxID txid_, kv::Store& store_, MapT& other_table_) :
txid(txid_),
store(store_),
other_table(other_table_)
@ -267,7 +267,7 @@ public:
kv::PendingTxInfo call() override
{
auto txr = store.create_reserved_tx(txid.version);
auto txr = store.create_reserved_tx(txid.seqno);
auto txrv = txr.rw(other_table);
txrv->put(0, 1);
return txr.commit_reserved();
@ -335,7 +335,7 @@ public:
rollback_to(rollback_to_)
{}
bool replicate(const kv::BatchVector& entries, View view) override
bool replicate(const kv::BatchVector& entries, ccf::View view) override
{
for (auto& [version, data, committable, hook] : entries)
{
@ -346,12 +346,12 @@ public:
return true;
}
std::pair<View, SeqNo> get_committed_txid() override
std::pair<ccf::View, ccf::SeqNo> get_committed_txid() override
{
return {2, 0};
}
SeqNo get_committed_seqno() override
ccf::SeqNo get_committed_seqno() override
{
return 0;
}
@ -366,12 +366,12 @@ public:
return kv::test::PrimaryNodeId;
}
View get_view(SeqNo seqno) override
ccf::View get_view(ccf::SeqNo seqno) override
{
return 2;
}
View get_view() override
ccf::View get_view() override
{
return 2;
}

Просмотреть файл

@ -36,18 +36,15 @@ public:
override);
MAKE_MOCK3(
sign_view_change_request,
void(
ccf::ViewChangeRequest& view_change,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno),
void(ccf::ViewChangeRequest& view_change, ccf::View view, ccf::SeqNo seqno),
override);
MAKE_MOCK4(
verify_view_change_request,
bool(
ccf::ViewChangeRequest& view_change,
const kv::NodeId& from,
kv::Consensus::View view,
kv::Consensus::SeqNo seqno),
ccf::View view,
ccf::SeqNo seqno),
override);
MAKE_MOCK2(
verify_view_change_request_confirmation,
@ -55,15 +52,15 @@ public:
override);
MAKE_MOCK1(
write_view_change_confirmation,
kv::Consensus::SeqNo(ccf::ViewChangeConfirmation& new_view),
ccf::SeqNo(ccf::ViewChangeConfirmation& new_view),
override);
};
void ordered_execution(
kv::NodeId my_node_id, std::unique_ptr<ccf::ProgressTracker>& pt)
{
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 42;
ccf::View view = 0;
ccf::SeqNo seqno = 42;
uint32_t node_count = 4;
uint32_t node_count_quorum =
2; // Takes into account that counting starts at 0
@ -311,7 +308,7 @@ TEST_CASE("Request tracker")
aft::RequestTracker t;
auto r = t.get_seqno_time_last_request();
REQUIRE(std::get<0>(r) == -1);
REQUIRE(std::get<0>(r) == ccf::SEQNO_UNKNOWN);
REQUIRE(std::get<1>(r) == std::chrono::milliseconds(0));
t.insert_signed_request(2, std::chrono::milliseconds(2));
@ -329,8 +326,8 @@ TEST_CASE("Request tracker")
TEST_CASE("Record primary signature")
{
kv::NodeId my_node_id = kv::test::PrimaryNodeId;
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 42;
ccf::View view = 0;
ccf::SeqNo seqno = 42;
crypto::Sha256Hash root;
ccf::Nonce nonce;
std::vector<uint8_t> primary_sig;
@ -357,8 +354,8 @@ TEST_CASE("View Changes")
StoreMock& store_mock = *store.get();
ccf::ProgressTracker pt(std::move(store), my_node_id);
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 42;
ccf::View view = 0;
ccf::SeqNo seqno = 42;
uint32_t node_count = 4;
uint32_t node_count_quorum =
2; // Takes into account that counting starts at 0
@ -423,7 +420,7 @@ TEST_CASE("View Changes")
INFO("Update latest prepared");
{
kv::Consensus::SeqNo new_seqno = 84;
ccf::SeqNo new_seqno = 84;
REQUIRE_CALL(store_mock, verify_signature(_, _, _, _))
.RETURN(true)
@ -476,7 +473,7 @@ TEST_CASE("View Changes")
INFO("Update older prepared");
{
kv::Consensus::SeqNo new_seqno = 21;
ccf::SeqNo new_seqno = 21;
REQUIRE_CALL(store_mock, verify_signature(_, _, _, _))
.RETURN(true)
@ -587,8 +584,8 @@ TEST_CASE("view-change-tracker timeout tests")
TEST_CASE("view-change-tracker statemachine tests")
{
ccf::ViewChangeRequest v;
kv::Consensus::View view = 3;
kv::Consensus::SeqNo seqno = 1;
ccf::View view = 3;
ccf::SeqNo seqno = 1;
uint32_t node_count = 4;
INFO("Can trigger view change");
@ -699,8 +696,8 @@ TEST_CASE("Sending evidence out of band")
using trompeloeil::_;
ccf::ViewChangeRequest v;
kv::Consensus::View view = 3;
kv::Consensus::SeqNo seqno = 1;
ccf::View view = 3;
ccf::SeqNo seqno = 1;
constexpr uint32_t node_count = 4;
INFO("Can trigger view change");

Просмотреть файл

@ -65,15 +65,14 @@ namespace ccf
struct ViewChangeConfirmation
{
kv::Consensus::View view = 0;
kv::Consensus::SeqNo seqno = 0;
ccf::View view = 0;
ccf::SeqNo seqno = 0;
std::vector<uint8_t> signature;
std::map<NodeId, ViewChangeRequest> view_change_messages;
ViewChangeConfirmation() = default;
ViewChangeConfirmation(
kv::Consensus::View view_, kv::Consensus::SeqNo seqno_) :
ViewChangeConfirmation(ccf::View view_, ccf::SeqNo seqno_) :
view(view_),
seqno(seqno_)
{}