diff --git a/src/hashdb64/database_64.cpp b/src/hashdb64/database_64.cpp index 1cf93774f..91a477b92 100644 --- a/src/hashdb64/database_64.cpp +++ b/src/hashdb64/database_64.cpp @@ -343,6 +343,7 @@ zkresult Database64::readKV(const Goldilocks::Element (&root)[4], const Goldiloc if (dbReadLog != NULL) dbReadLog->add(keyStr, value, true, TimeDiff(t)); rkv = ZKR_SUCCESS; + rout = rkv; } // If the key is pending to be stored in database, but already deleted from cache diff --git a/src/hashdb64/state_manager_64.cpp b/src/hashdb64/state_manager_64.cpp index 5c039dae7..be3b39fb2 100644 --- a/src/hashdb64/state_manager_64.cpp +++ b/src/hashdb64/state_manager_64.cpp @@ -52,6 +52,20 @@ zkresult StateManager64::setStateRoot(const string &batchUUID, uint64_t tx, cons state[batchUUID] = batchState; it = state.find(batchUUID); zkassert(it != state.end()); + + // Copy the previous batch state dbWrite map + for (int64_t i = stateOrder.size() - 1; i >= 0; i--) + { + unordered_map::iterator previt; + previt = state.find(stateOrder[i]); + zkassert(previt != state.end()); + if (previt->second.currentStateRoot == stateRoot) + { + it->second.dbWrite = previt->second.dbWrite; + break; + } + } + stateOrder.emplace_back(batchUUID); } BatchState64 &batchState = it->second; @@ -872,6 +886,14 @@ zkresult StateManager64::consolidateState(const string &_virtualStateRoot, const // Return the consolidated state root consolidatedStateRoot = fea2string(fr, newRoot); + // Copy it to use it when reading a KV that is not in the StateManager, + // and we have to read it from database using a consolidated state root + lastConsolidatedStateRoot[0] = newRoot[0]; + lastConsolidatedStateRoot[1] = newRoot[1]; + lastConsolidatedStateRoot[2] = newRoot[2]; + lastConsolidatedStateRoot[3] = newRoot[3]; + lastConsolidatedStateRootString = consolidatedStateRoot; + // Call flush and get the flush ID zkr = db.flush(flushId, lastSentFlushId); @@ -1123,11 +1145,11 @@ zkresult StateManager64::get (const string &batchUUID, Database64 &db, const Gol } if (zkr != ZKR_SUCCESS) { - zkr = db.readKV(root, key, value, level, dbReadLog); + zkr = db.readKV(lastConsolidatedStateRoot, key, value, level, dbReadLog); } if (zkr != ZKR_SUCCESS) { - zklog.error("StateManager64::get() db.read error: " + to_string(zkr) + " (" + zkresult2string(zkr) + ") root:" + fea2string(fr, root)); + zklog.error("StateManager64::get() db.read error=" + zkresult2string(zkr) + " root=" + fea2string(fr, lastConsolidatedStateRoot) + " key=" + fea2string(fr, key)); return zkr; } diff --git a/src/hashdb64/state_manager_64.hpp b/src/hashdb64/state_manager_64.hpp index 5591add95..8c7bb3293 100644 --- a/src/hashdb64/state_manager_64.hpp +++ b/src/hashdb64/state_manager_64.hpp @@ -78,11 +78,17 @@ class StateManager64 Config config; pthread_mutex_t mutex; // Mutex to protect the multi write queues uint64_t lastVirtualStateRoot; + Goldilocks::Element lastConsolidatedStateRoot[4]; + string lastConsolidatedStateRootString; public: StateManager64(Goldilocks &fr, PoseidonGoldilocks &poseidon) : fr(fr), poseidon(poseidon), lastVirtualStateRoot(0) { // Init mutex pthread_mutex_init(&mutex, NULL); + lastConsolidatedStateRoot[0] = fr.zero(); + lastConsolidatedStateRoot[1] = fr.zero(); + lastConsolidatedStateRoot[2] = fr.zero(); + lastConsolidatedStateRoot[3] = fr.zero(); }; private: zkresult setStateRoot (const string &batchUUID, uint64_t tx, const string &stateRoot, const bool bIsOldStateRoot, const Persistence persistence); diff --git a/test/service/hashdb/hashdb64_workflow_test.cpp b/test/service/hashdb/hashdb64_workflow_test.cpp index d74c23275..16a31394c 100644 --- a/test/service/hashdb/hashdb64_workflow_test.cpp +++ b/test/service/hashdb/hashdb64_workflow_test.cpp @@ -23,9 +23,11 @@ uint64_t HashDB64WorkflowTest (const Config& config) uint64_t flushId, storedFlushId; - const uint64_t numberOfSetsPerTx = 3; - const uint64_t numberOfTxsPerBatch = 3; const uint64_t numberOfBatches = 10; + const uint64_t numberOfTxsPerBatch = 3; + const uint64_t numberOfSetsPerTx = 3; + + zklog.info("HashDB64WorkflowTest() numberOfBatches=" + to_string(numberOfBatches) + " numberOfTxsPerBatch=" + to_string(numberOfTxsPerBatch) + " numberOfSetsPerTx=" + to_string(numberOfSetsPerTx)); SmtSetResult setResult; SmtGetResult getResult; @@ -36,10 +38,11 @@ uint64_t HashDB64WorkflowTest (const Config& config) Goldilocks::Element keyfea[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; mpz_class value = 0; mpz_class keyScalar = 0; + vector allKeyValues; for (uint64_t batch=0; batch