Skip to content

Commit

Permalink
Create HashDB::writeTree and readTree, and use them in Smt64Test
Browse files Browse the repository at this point in the history
  • Loading branch information
fractasy committed Aug 31, 2023
1 parent aa886e5 commit 54a78db
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 31 deletions.
6 changes: 6 additions & 0 deletions src/hashdb64/smt_64.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include "key_utils.hpp"
#include "tree_chunk.hpp"

//#define SMT64_PRINT_TREE_CHUNKS

zkresult Smt64::writeTree (Database64 &db, const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId)
{
zkresult zkr;
Expand Down Expand Up @@ -260,12 +262,14 @@ zkresult Smt64::writeTree (Database64 &db, const Goldilocks::Element (&oldRoot)[
return zkr;
}

#ifdef SMT64_PRINT_TREE_CHUNKS
// Print chunks
for (uint c = 0; c < chunks.size(); c++)
{
zklog.info("Smt64::writeTree() chunk " + to_string(c));
chunks[c]->print();
}
#endif

// Free memory
for (uint c = 0; c < chunks.size(); c++) delete chunks[c];
Expand Down Expand Up @@ -491,12 +495,14 @@ zkresult Smt64::readTree (Database64 &db, const Goldilocks::Element (&root)[4],

dbQueries.clear();

#ifdef SMT64_PRINT_TREE_CHUNKS
// Print chunks
for (uint c = 0; c < chunks.size(); c++)
{
zklog.info("Smt64::readTree() chunk " + to_string(c));
chunks[c]->print();
}
#endif

// Free memory
for (uint c = 0; c < chunks.size(); c++) delete chunks[c];
Expand Down
10 changes: 5 additions & 5 deletions src/hashdb64/tree_chunk.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ zkresult TreeChunk::calculateHash (void)
}
bChildrenRestValid = false;

TimerStart(TREE_CHUNK_CALCULATE_HASH);
//TimerStart(TREE_CHUNK_CALCULATE_HASH);

if (level%6 != 0)
{
Expand Down Expand Up @@ -335,7 +335,7 @@ zkresult TreeChunk::calculateHash (void)
bHashValid = true;
bChildrenRestValid = true;

TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);
//TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);

return ZKR_SUCCESS;
}
Expand All @@ -351,7 +351,7 @@ zkresult TreeChunk::calculateHash (void)
bHashValid = true;
bChildrenRestValid = true;

TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);
//TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);

return ZKR_SUCCESS;
}
Expand All @@ -367,14 +367,14 @@ zkresult TreeChunk::calculateHash (void)
bHashValid = true;
bChildrenRestValid = true;

TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);
//TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);

return ZKR_SUCCESS;
}
default:
{
zklog.error("TreeChunk::calculateHash() found unexpected child1.type=" + to_string(child1.type));
TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);
//TimerStopAndLog(TREE_CHUNK_CALCULATE_HASH);
return ZKR_UNSPECIFIED;
}
}
Expand Down
26 changes: 26 additions & 0 deletions src/service/hashdb/hashdb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,32 @@ void HashDB::clearCache(void)
}
}

zkresult HashDB::readTree (const Goldilocks::Element (&root)[4], vector<KeyValue> &keyValues)
{
if (config.hashDB64)
{
return smt64.readTree(db64, root, keyValues);
}
else
{
zklog.error("HashDB::readTree() called with config.hashDB64=false");
return ZKR_UNSPECIFIED;
}
}

zkresult HashDB::writeTree (const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId)
{
if (config.hashDB64)
{
return smt64.writeTree(db64, oldRoot, keyValues, newRoot, flushId, lastSentFlushId);
}
else
{
zklog.error("HashDB::writeTree() called with config.hashDB64=false");
return ZKR_UNSPECIFIED;
}
}

void HashDB::setAutoCommit(const bool autoCommit)
{
#ifdef LOG_TIME_STATISTICS_HASHDB
Expand Down
2 changes: 2 additions & 0 deletions src/service/hashdb/hashdb.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@ class HashDB : public HashDBInterface
zkresult getFlushStatus (uint64_t &storedFlushId, uint64_t &storingFlushId, uint64_t &lastFlushId, uint64_t &pendingToFlushNodes, uint64_t &pendingToFlushProgram, uint64_t &storingNodes, uint64_t &storingProgram, string &proverId);
zkresult getFlushData (uint64_t flushId, uint64_t &storedFlushId, unordered_map<string, string> (&nodes), unordered_map<string, string> (&program), string &nodesStateRoot);
void clearCache (void);
zkresult readTree (const Goldilocks::Element (&root)[4], vector<KeyValue> &keyValues);
zkresult writeTree (const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId);

// Methods added for testing purposes
void setAutoCommit(const bool autoCommit);
Expand Down
5 changes: 5 additions & 0 deletions src/service/hashdb/hashdb_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
#include <mutex>
#include "zkresult.hpp"
#include "persistence.hpp"
#include "database_64.hpp"
#include "key_value.hpp"

class HashDBInterface
{
Expand All @@ -27,6 +29,9 @@ class HashDBInterface
virtual zkresult getFlushStatus (uint64_t &storedFlushId, uint64_t &storingFlushId, uint64_t &lastFlushId, uint64_t &pendingToFlushNodes, uint64_t &pendingToFlushProgram, uint64_t &storingNodes, uint64_t &storingProgram, string &proverId) = 0;
virtual zkresult getFlushData (uint64_t flushId, uint64_t &storedFlushId, unordered_map<string, string> (&nodes), unordered_map<string, string> (&program), string &nodesStateRoot) = 0;
virtual void clearCache (void) = 0;
virtual zkresult readTree (const Goldilocks::Element (&root)[4], vector<KeyValue> &keyValues) = 0;
virtual zkresult writeTree (const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId) = 0;

};

#endif
12 changes: 12 additions & 0 deletions src/service/hashdb/hashdb_remote.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,15 @@ zkresult HashDBRemote::getFlushData(uint64_t flushId, uint64_t &storedFlushId, u

return ZKR_SUCCESS;
}

zkresult HashDBRemote::readTree (const Goldilocks::Element (&root)[4], vector<KeyValue> &keyValues)
{
zklog.error("HashDBRemote::readTree() called, but this method is only allowed locally");
return ZKR_UNSPECIFIED;
}

zkresult HashDBRemote::writeTree (const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId)
{
zklog.error("HashDBRemote::writeTree() called, but this method is only allowed locally");
return ZKR_UNSPECIFIED;
}
3 changes: 3 additions & 0 deletions src/service/hashdb/hashdb_remote.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "zkresult.hpp"
#include "utils/time_metric.hpp"
#include "timer.hpp"
#include "database_64.hpp"

class HashDBRemote : public HashDBInterface
{
Expand Down Expand Up @@ -41,6 +42,8 @@ class HashDBRemote : public HashDBInterface
zkresult getFlushStatus (uint64_t &storedFlushId, uint64_t &storingFlushId, uint64_t &lastFlushId, uint64_t &pendingToFlushNodes, uint64_t &pendingToFlushProgram, uint64_t &storingNodes, uint64_t &storingProgram, string &proverId);
zkresult getFlushData (uint64_t flushId, uint64_t &storedFlushId, unordered_map<string, string> (&nodes), unordered_map<string, string> (&program), string &nodesStateRoot);
void clearCache (void) {};
zkresult readTree (const Goldilocks::Element (&root)[4], vector<KeyValue> &keyValues);
zkresult writeTree (const Goldilocks::Element (&oldRoot)[4], const vector<KeyValue> &keyValues, Goldilocks::Element (&newRoot)[4], uint64_t &flushId, uint64_t &lastSentFlushId);
};

#endif
55 changes: 29 additions & 26 deletions test/hashdb/smt_64_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,27 @@
#include "smt.hpp"
#include "hashdb_singleton.hpp"
#include "unistd.h"
#include "hashdb_factory.hpp"

#define SMT64_TEST_NUMBER_OF_KEYS 10

uint64_t Smt64Test (const Config &config)
{
TimerStart(SMT64_TEST);

uint64_t numberOfFailedTests = 0;
Goldilocks::Element root[4] = {0, 0, 0, 0};
Goldilocks fr;
zkresult zkr;
vector<KeyValue> keyValues;

HashDBInterface *pHashDB = HashDBClientFactory::createHashDBClient(fr, config);
if (pHashDB == NULL)
{
zklog.error("Smt64Test() failed calling HashDBClientFactory::createHashDBClient()");
return 1;
}

// Init the keyValues
for (uint64_t i=0; i<SMT64_TEST_NUMBER_OF_KEYS; i++)
{
Expand All @@ -29,49 +39,52 @@ uint64_t Smt64Test (const Config &config)
// Perform the test, based on the configuration
if (config.hashDB64)
{
Smt64 smt64(fr);
Database64 db64(fr, config);
db64.init();
// Call writeTree()
uint64_t flushId = 0;
uint64_t lastSentFlushId = 0;

zkr = smt64.writeTree(db64, root, keyValues, root, flushId, lastSentFlushId);
zkr = pHashDB->writeTree(root, keyValues, root, flushId, lastSentFlushId);
if (zkr != ZKR_SUCCESS)
{
zklog.error("Smt64Test() failed calling smt64.writeTree() result=" + zkresult2string(zkr));
return 1;
}
zklog.info("Smt64Test() smt64.writeTree() returned root=" + fea2string(fr, root) + " flushId=" + to_string(flushId));
//zklog.info("Smt64Test() smt64.writeTree() returned root=" + fea2string(fr, root) + " flushId=" + to_string(flushId));

// Wait for the returned flush ID to be sent
do
{
uint64_t storedFlushId, storingFlushId, lastFlushId, pendingToFlushNodes, pendingToFlushProgram, storingNodes, storingProgram;
zkr = db64.getFlushStatus(storedFlushId, storingFlushId, lastFlushId, pendingToFlushNodes, pendingToFlushProgram, storingNodes, storingProgram);
string proverId;
zkr = pHashDB->getFlushStatus(storedFlushId, storingFlushId, lastFlushId, pendingToFlushNodes, pendingToFlushProgram, storingNodes, storingProgram, proverId);
if (zkr != ZKR_SUCCESS)
{
zklog.error("Smt64Test() failed calling db64.getFlushStatus() result=" + zkresult2string(zkr));
return 1;
}
if (storedFlushId >= flushId)
{
zklog.info("Smt64Test() called db64.getFlushStatus() and got storedFlushId=" + to_string(storedFlushId) + " >= flushId=" + to_string(flushId));
//zklog.info("Smt64Test() called db64.getFlushStatus() and got storedFlushId=" + to_string(storedFlushId) + " >= flushId=" + to_string(flushId));
break;
}
sleep(1);
} while (true);


// Make a copy of the key values, overwriting the value with an invalid value
vector<KeyValue> readKeyValues = keyValues;
for (uint64_t i=0; i<readKeyValues.size(); i++)
{
readKeyValues[i].value = 0xFFFFFFFFFFFFFFFF;
}
zkr = smt64.readTree(db64, root, readKeyValues);

// Call readTree() with the returned root
zkr = pHashDB->readTree(root, readKeyValues);
if (zkr != ZKR_SUCCESS)
{
zklog.error("Smt64Test() failed calling smt64.readTree() result=" + zkresult2string(zkr));
return 1;
}

// Check that both keys and values match the ones we wrote
for (uint64_t i=0; i<SMT64_TEST_NUMBER_OF_KEYS; i++)
{
// Check that the key is still the same
Expand All @@ -91,38 +104,28 @@ uint64_t Smt64Test (const Config &config)
numberOfFailedTests++;
}
}

// Announce the success
if (numberOfFailedTests==0)
{
zklog.info("Smt64Test() succeeded");
sleep(1);
}


}
else
{
Smt smt(fr);
Database db(fr, config);
db.init();

for (uint64_t i=0; i<SMT64_TEST_NUMBER_OF_KEYS; i++)
{
SmtSetResult smtSetResult;
zkr = smt.set("", 0, db, root, keyValues[i].key.fe, keyValues[i].value, PERSISTENCE_DATABASE, smtSetResult);
zkr = pHashDB->set("", 0, root, keyValues[i].key.fe, keyValues[i].value, PERSISTENCE_DATABASE, root, NULL, NULL);
if (zkr != ZKR_SUCCESS)
{
zklog.error("Smt64Test() failed calling smt.set() result=" + zkresult2string(zkr));
zklog.error("Smt64Test() failed calling pHashDB->set() result=" + zkresult2string(zkr));
return 1;
}
root[0] = smtSetResult.newRoot[0];
root[1] = smtSetResult.newRoot[1];
root[2] = smtSetResult.newRoot[2];
root[3] = smtSetResult.newRoot[3];
zklog.info("Smt64Test() smt.set() i=" + to_string(i) + " returned root=" + fea2string(fr, root));
zklog.info("Smt64Test() pHashDB->set() i=" + to_string(i) + " returned root=" + fea2string(fr, root));
}
}

//sleep(2);
TimerStopAndLog(SMT64_TEST);

return numberOfFailedTests;
}

0 comments on commit 54a78db

Please sign in to comment.