|
20 | 20 | #include <unistd.h> |
21 | 21 | #include <algorithm> |
22 | 22 | #include <variant> |
| 23 | +#include <nlohmann/json.hpp> |
23 | 24 | #include "ReplicaConfig.hpp" |
24 | 25 | #include "kvbc_key_types.hpp" |
25 | 26 |
|
@@ -64,6 +65,34 @@ static const std::string &keyHashToCategory(const Hash &keyHash) { |
64 | 65 |
|
65 | 66 | static const std::string &keyToCategory(const std::string &key) { return keyHashToCategory(createHash(key)); } |
66 | 67 |
|
| 68 | +InternalCommandsHandler::InternalCommandsHandler(concord::kvbc::IReader *storage, |
| 69 | + concord::kvbc::IBlockAdder *blocksAdder, |
| 70 | + concord::kvbc::IBlockMetadata *blockMetadata, |
| 71 | + logging::Logger &logger, |
| 72 | + bftEngine::IStateTransfer &st, |
| 73 | + bool addAllKeysAsPublic, |
| 74 | + concord::kvbc::adapter::ReplicaBlockchain *kvbc) |
| 75 | + : m_storage(storage), |
| 76 | + m_blockAdder(blocksAdder), |
| 77 | + m_blockMetadata(blockMetadata), |
| 78 | + m_logger(logger), |
| 79 | + m_addAllKeysAsPublic{addAllKeysAsPublic}, |
| 80 | + m_kvbc{kvbc} { |
| 81 | + st.addOnTransferringCompleteCallback([this](uint64_t) { |
| 82 | + LOG_INFO(GL, "Synchronizing client execution state after state transfer"); |
| 83 | + auto data = m_storage->getLatest(CLIENT_STATE_CAT_ID, {0x1}); |
| 84 | + ConcordAssert(data.has_value()); |
| 85 | + auto raw_json = std::get<concord::kvbc::categorization::VersionedValue>(data.value()).data; |
| 86 | + nlohmann::json json2 = nlohmann::json::parse(raw_json); |
| 87 | + nlohmann::json::json_serializer<std::unordered_map<uint16_t, uint64_t>, void> serializer; |
| 88 | + serializer.from_json(json2, m_clientToMaxExecutedReqId); |
| 89 | + LOG_INFO(GL, "raw client state: " << KVLOG(raw_json)); |
| 90 | + }); |
| 91 | + if (m_addAllKeysAsPublic) { |
| 92 | + ConcordAssertNE(m_kvbc, nullptr); |
| 93 | + } |
| 94 | +} |
| 95 | + |
67 | 96 | void InternalCommandsHandler::add(std::string &&key, |
68 | 97 | std::string &&value, |
69 | 98 | VersionedUpdates &verUpdates, |
@@ -318,7 +347,15 @@ void InternalCommandsHandler::writeAccumulatedBlock(ExecutionRequestsQueue &bloc |
318 | 347 | "SKVBCWrite message handled; writesCounter=" << m_writesCounter << " currBlock=" << write_rep.latest_block); |
319 | 348 | } |
320 | 349 | } |
321 | | - addBlock(verUpdates, merkleUpdates, sn); |
| 350 | + |
| 351 | + nlohmann::json json; |
| 352 | + nlohmann::json::json_serializer<std::unordered_map<uint16_t, uint64_t>, void> serializer; |
| 353 | + serializer.to_json(json, m_clientToMaxExecutedReqId); |
| 354 | + |
| 355 | + VersionedUpdates clientStateUpdate; |
| 356 | + clientStateUpdate.addUpdate({0x1}, json.dump()); |
| 357 | + |
| 358 | + addBlock(verUpdates, merkleUpdates, clientStateUpdate, sn); |
322 | 359 | } |
323 | 360 |
|
324 | 361 | OperationResult InternalCommandsHandler::verifyWriteCommand(uint32_t requestSize, |
@@ -364,7 +401,10 @@ void InternalCommandsHandler::addKeys(const SKVBCWriteRequest &writeReq, |
364 | 401 | addMetadataKeyValue(verUpdates, sequenceNum); |
365 | 402 | } |
366 | 403 |
|
367 | | -void InternalCommandsHandler::addBlock(VersionedUpdates &verUpdates, BlockMerkleUpdates &merkleUpdates, uint64_t sn) { |
| 404 | +void InternalCommandsHandler::addBlock(VersionedUpdates &verUpdates, |
| 405 | + BlockMerkleUpdates &merkleUpdates, |
| 406 | + VersionedUpdates &clientStateVerUpdates, |
| 407 | + uint64_t sn) { |
368 | 408 | BlockId currBlock = m_storage->getLastBlockId(); |
369 | 409 | Updates updates; |
370 | 410 |
|
@@ -396,6 +436,7 @@ void InternalCommandsHandler::addBlock(VersionedUpdates &verUpdates, BlockMerkle |
396 | 436 | updates.add(kConcordInternalCategoryId, std::move(internal_updates)); |
397 | 437 | updates.add(VERSIONED_KV_CAT_ID, std::move(verUpdates)); |
398 | 438 | updates.add(BLOCK_MERKLE_CAT_ID, std::move(merkleUpdates)); |
| 439 | + updates.add(CLIENT_STATE_CAT_ID, std::move(clientStateVerUpdates)); |
399 | 440 | const auto newBlockId = m_blockAdder->add(std::move(updates)); |
400 | 441 | ConcordAssert(newBlockId == currBlock + 1); |
401 | 442 | } |
@@ -483,29 +524,35 @@ OperationResult InternalCommandsHandler::executeWriteCommand(uint32_t requestSiz |
483 | 524 | hasConflict = hasConflict || (!isFirstClientRequest && m_clientToMaxExecutedReqId[clientId] >= requestId); |
484 | 525 | } |
485 | 526 |
|
| 527 | + SKVBCReply reply; |
| 528 | + reply.reply = SKVBCWriteReply(); |
| 529 | + SKVBCWriteReply &write_rep = std::get<SKVBCWriteReply>(reply.reply); |
| 530 | + write_rep.success = !hasConflict; |
486 | 531 | if (!hasConflict) { |
| 532 | + write_rep.latest_block = currBlock + 1; |
| 533 | + auto [iter, isNew] = m_clientToMaxExecutedReqId.emplace(clientId, 0); |
| 534 | + UNUSED(iter); |
| 535 | + UNUSED(isNew); |
| 536 | + m_clientToMaxExecutedReqId[clientId] = std::max(m_clientToMaxExecutedReqId[clientId], batchCid); |
| 537 | + |
487 | 538 | if (isBlockAccumulationEnabled) { |
488 | 539 | // If Block Accumulation is enabled then blocks are added after all requests are processed |
489 | 540 | addKeys(write_req, sequenceNum, blockAccumulatedVerUpdates, blockAccumulatedMerkleUpdates); |
490 | 541 | } else { |
491 | 542 | // If Block Accumulation is not enabled then blocks are added after all requests are processed |
492 | 543 | VersionedUpdates verUpdates; |
493 | 544 | BlockMerkleUpdates merkleUpdates; |
| 545 | + VersionedUpdates clientVerUpdates; |
| 546 | + nlohmann::json json; |
| 547 | + nlohmann::json::json_serializer<std::unordered_map<uint16_t, uint64_t>, void> serializer; |
| 548 | + serializer.to_json(json, m_clientToMaxExecutedReqId); |
| 549 | + auto dump = json.dump(); |
| 550 | + LOG_INFO(GL, KVLOG(dump)); |
| 551 | + clientVerUpdates.addUpdate({0x1}, json.dump()); |
494 | 552 | addKeys(write_req, sequenceNum, verUpdates, merkleUpdates); |
495 | | - addBlock(verUpdates, merkleUpdates, sequenceNum); |
| 553 | + addBlock(verUpdates, merkleUpdates, clientVerUpdates, sequenceNum); |
496 | 554 | } |
497 | | - } |
498 | 555 |
|
499 | | - SKVBCReply reply; |
500 | | - reply.reply = SKVBCWriteReply(); |
501 | | - SKVBCWriteReply &write_rep = std::get<SKVBCWriteReply>(reply.reply); |
502 | | - write_rep.success = !hasConflict; |
503 | | - if (!hasConflict) { |
504 | | - write_rep.latest_block = currBlock + 1; |
505 | | - auto [iter, isNew] = m_clientToMaxExecutedReqId.emplace(clientId, 0); |
506 | | - UNUSED(iter); |
507 | | - UNUSED(isNew); |
508 | | - m_clientToMaxExecutedReqId[clientId] = std::max(m_clientToMaxExecutedReqId[clientId], batchCid); |
509 | 556 | } else { |
510 | 557 | write_rep.latest_block = currBlock; |
511 | 558 | } |
|
0 commit comments