Use fully static linkage #364
4 changed files with 26 additions and 79 deletions
|
@ -50,29 +50,29 @@ CClaimTrie::CClaimTrie(bool fWipe, int height, int proportionalDelayFactor)
|
||||||
: dbPath((GetDataDir() / "claims.sqlite").string()), db(dbPath, sharedConfig),
|
: dbPath((GetDataDir() / "claims.sqlite").string()), db(dbPath, sharedConfig),
|
||||||
nNextHeight(height), nProportionalDelayFactor(proportionalDelayFactor)
|
nNextHeight(height), nProportionalDelayFactor(proportionalDelayFactor)
|
||||||
{
|
{
|
||||||
db.define("MERKLE_ROOT", [](std::vector<uint256>& hashes, const std::vector<unsigned char>& blob) { hashes.emplace_back(uint256(blob)); },
|
// db.define("MERKLE_ROOT", [](std::vector<uint256>& hashes, const std::vector<unsigned char>& blob) { hashes.emplace_back(uint256(blob)); },
|
||||||
[](const std::vector<uint256>& hashes) { return ComputeMerkleRoot(hashes); });
|
// [](const std::vector<uint256>& hashes) { return ComputeMerkleRoot(hashes); });
|
||||||
|
//
|
||||||
|
// db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
||||||
|
// db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
||||||
|
|
||||||
db.define("MERKLE_PAIR", [](const std::vector<unsigned char>& blob1, const std::vector<unsigned char>& blob2) { return Hash(blob1.begin(), blob1.end(), blob2.begin(), blob2.end()); });
|
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB COLLATE BINARY, takeoverHeight INTEGER, takeoverID BLOB COLLATE BINARY)";
|
||||||
db.define("MERKLE", [](const std::vector<unsigned char>& blob1) { return Hash(blob1.begin(), blob1.end()); });
|
|
||||||
|
|
||||||
db << "CREATE TABLE IF NOT EXISTS nodes (name TEXT NOT NULL PRIMARY KEY, parent TEXT, hash BLOB, takeoverHeight INTEGER, takeoverID BLOB)";
|
|
||||||
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
db << "CREATE INDEX IF NOT EXISTS nodes_hash ON nodes (hash)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
db << "CREATE INDEX IF NOT EXISTS nodes_parent ON nodes (parent)";
|
||||||
|
|
||||||
db << "CREATE TABLE IF NOT EXISTS claims (claimID BLOB NOT NULL PRIMARY KEY, name TEXT NOT NULL, "
|
db << "CREATE TABLE IF NOT EXISTS claims (claimID BLOB NOT NULL COLLATE BINARY PRIMARY KEY, name TEXT NOT NULL, "
|
||||||
"nodeName TEXT NOT NULL REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, "
|
"nodeName TEXT NOT NULL REFERENCES nodes(name) DEFERRABLE INITIALLY DEFERRED, "
|
||||||
"txID BLOB NOT NULL, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, "
|
"txID BLOB NOT NULL COLLATE BINARY, txN INTEGER NOT NULL, blockHeight INTEGER NOT NULL, "
|
||||||
"validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
"validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
||||||
"amount INTEGER NOT NULL, metadata BLOB);";
|
"amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY);";
|
||||||
db << "CREATE INDEX IF NOT EXISTS claims_validHeight ON claims (validHeight)";
|
db << "CREATE INDEX IF NOT EXISTS claims_validHeight ON claims (validHeight)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS claims_expirationHeight ON claims (expirationHeight)";
|
db << "CREATE INDEX IF NOT EXISTS claims_expirationHeight ON claims (expirationHeight)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS claims_nodeName ON claims (nodeName)";
|
db << "CREATE INDEX IF NOT EXISTS claims_nodeName ON claims (nodeName)";
|
||||||
|
|
||||||
db << "CREATE TABLE IF NOT EXISTS supports (txID BLOB NOT NULL, txN INTEGER NOT NULL, "
|
db << "CREATE TABLE IF NOT EXISTS supports (txID BLOB NOT NULL COLLATE BINARY, txN INTEGER NOT NULL, "
|
||||||
"supportedClaimID BLOB NOT NULL, name TEXT NOT NULL, nodeName TEXT NOT NULL, "
|
"supportedClaimID BLOB NOT NULL COLLATE BINARY, name TEXT NOT NULL, nodeName TEXT NOT NULL, "
|
||||||
"blockHeight INTEGER NOT NULL, validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
"blockHeight INTEGER NOT NULL, validHeight INTEGER NOT NULL, expirationHeight INTEGER NOT NULL, "
|
||||||
"amount INTEGER NOT NULL, metadata BLOB, PRIMARY KEY(txID, txN));";
|
"amount INTEGER NOT NULL, metadata BLOB COLLATE BINARY, PRIMARY KEY(txID, txN));";
|
||||||
db << "CREATE INDEX IF NOT EXISTS supports_supportedClaimID ON supports (supportedClaimID)";
|
db << "CREATE INDEX IF NOT EXISTS supports_supportedClaimID ON supports (supportedClaimID)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS supports_validHeight ON supports (validHeight)";
|
db << "CREATE INDEX IF NOT EXISTS supports_validHeight ON supports (validHeight)";
|
||||||
db << "CREATE INDEX IF NOT EXISTS supports_expirationHeight ON supports (expirationHeight)";
|
db << "CREATE INDEX IF NOT EXISTS supports_expirationHeight ON supports (expirationHeight)";
|
||||||
|
@ -230,7 +230,7 @@ void CClaimTrieCacheBase::ensureTreeStructureIsUpToDate() {
|
||||||
auto parentQuery = db << "SELECT name FROM nodes WHERE "
|
auto parentQuery = db << "SELECT name FROM nodes WHERE "
|
||||||
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
||||||
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
||||||
"ORDER BY LENGTH(name) DESC LIMIT 1";
|
"ORDER BY name DESC LIMIT 1";
|
||||||
|
|
||||||
for (auto& name: names) {
|
for (auto& name: names) {
|
||||||
std::vector<std::string> claims;
|
std::vector<std::string> claims;
|
||||||
|
@ -328,7 +328,7 @@ bool CClaimTrieCacheBase::getInfoForName(const std::string& name, CClaimValue& c
|
||||||
auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, "
|
auto query = db << "SELECT c.claimID, c.txID, c.txN, c.blockHeight, c.validHeight, c.amount, "
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
||||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN LIMIT 1"
|
"ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN LIMIT 1"
|
||||||
<< nextHeight << nextHeight << name << nextHeight << nextHeight;
|
<< nextHeight << nextHeight << name << nextHeight << nextHeight;
|
||||||
for (auto&& row: query) {
|
for (auto&& row: query) {
|
||||||
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
row >> claim.claimId >> claim.outPoint.hash >> claim.outPoint.n
|
||||||
|
@ -493,6 +493,8 @@ CClaimTrieCacheBase::CClaimTrieCacheBase(CClaimTrie* base)
|
||||||
db << "PRAGMA journal_mode=MEMORY";
|
db << "PRAGMA journal_mode=MEMORY";
|
||||||
db << "PRAGMA temp_store=MEMORY";
|
db << "PRAGMA temp_store=MEMORY";
|
||||||
db << "PRAGMA case_sensitive_like=true";
|
db << "PRAGMA case_sensitive_like=true";
|
||||||
|
|
||||||
|
db.define("REVERSE_BYTES", [](std::vector<unsigned char> blob) { std::reverse(blob.begin(), blob.end()); return blob; });
|
||||||
}
|
}
|
||||||
|
|
||||||
int CClaimTrieCacheBase::expirationTime() const
|
int CClaimTrieCacheBase::expirationTime() const
|
||||||
|
@ -1256,7 +1258,7 @@ bool CClaimTrieCacheBase::getProofForName(const std::string& name, const uint160
|
||||||
auto nodeQuery = db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE "
|
auto nodeQuery = db << "SELECT name, IFNULL(takeoverHeight, 0) FROM nodes WHERE "
|
||||||
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
"name IN (WITH RECURSIVE prefix(p) AS (VALUES(?) UNION ALL "
|
||||||
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
"SELECT SUBSTR(p, 1, LENGTH(p)-1) FROM prefix WHERE p != '') SELECT p FROM prefix) "
|
||||||
"ORDER BY LENGTH(name)" << name;
|
"ORDER BY name" << name;
|
||||||
for (auto&& row: nodeQuery) {
|
for (auto&& row: nodeQuery) {
|
||||||
CClaimValue claim;
|
CClaimValue claim;
|
||||||
std::string key;
|
std::string key;
|
||||||
|
|
|
@ -20,18 +20,16 @@
|
||||||
|
|
||||||
namespace sqlite
|
namespace sqlite
|
||||||
{
|
{
|
||||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint160& vec) {
|
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint160& val) {
|
||||||
void const* buf = reinterpret_cast<void const *>(vec.begin());
|
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||||
return sqlite3_bind_blob(stmt, inx, buf, int(vec.size()), SQLITE_STATIC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint256& vec) {
|
inline int bind_col_in_db(sqlite3_stmt* stmt, int inx, const uint256& val) {
|
||||||
void const* buf = reinterpret_cast<void const *>(vec.begin());
|
return sqlite3_bind_blob(stmt, inx, val.begin(), int(val.size()), SQLITE_STATIC);
|
||||||
return sqlite3_bind_blob(stmt, inx, buf, int(vec.size()), SQLITE_STATIC);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void store_result_in_db(sqlite3_context* db, const uint160& val) {
|
inline void store_result_in_db(sqlite3_context* db, const uint160& val) {
|
||||||
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT);
|
sqlite3_result_blob(db, val.begin(), int(val.size()), SQLITE_TRANSIENT); // I think we need transient here but I'm not 100% sure
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void store_result_in_db(sqlite3_context* db, const uint256& val) {
|
inline void store_result_in_db(sqlite3_context* db, const uint256& val) {
|
||||||
|
|
|
@ -264,7 +264,7 @@ uint256 CClaimTrieCacheHashFork::recursiveComputeMerkleHash(const std::string& n
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||||
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
||||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN"
|
"ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN"
|
||||||
<< nNextHeight << nNextHeight << name << nNextHeight << nNextHeight;
|
<< nNextHeight << nNextHeight << name << nNextHeight << nNextHeight;
|
||||||
|
|
||||||
std::vector<uint256> claimHashes;
|
std::vector<uint256> claimHashes;
|
||||||
|
@ -363,7 +363,7 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
||||||
row >> key >> takeoverHeight;
|
row >> key >> takeoverHeight;
|
||||||
std::vector<uint256> childHashes;
|
std::vector<uint256> childHashes;
|
||||||
uint32_t nextCurrentIdx = 0;
|
uint32_t nextCurrentIdx = 0;
|
||||||
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ?" << key;
|
auto childQuery = db << "SELECT name, hash FROM nodes WHERE parent = ? ORDER BY name" << key;
|
||||||
for (auto&& child : childQuery) {
|
for (auto&& child : childQuery) {
|
||||||
std::string childKey;
|
std::string childKey;
|
||||||
uint256 childHash;
|
uint256 childHash;
|
||||||
|
@ -377,8 +377,8 @@ bool CClaimTrieCacheHashFork::getProofForName(const std::string& name, const uin
|
||||||
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
"(SELECT TOTAL(s.amount)+c.amount FROM supports s WHERE s.supportedClaimID = c.claimID "
|
||||||
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
"AND s.validHeight < ? AND s.expirationHeight >= ?) as effectiveAmount "
|
||||||
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
"FROM claims c WHERE c.nodeName = ? AND c.validHeight < ? AND c.expirationHeight >= ? "
|
||||||
"ORDER BY effectiveAmount DESC, c.blockHeight, c.txID, c.txN"
|
"ORDER BY effectiveAmount DESC, c.blockHeight, REVERSE_BYTES(c.txID), c.txN"
|
||||||
<< nNextHeight << nNextHeight << name << nNextHeight << nNextHeight;
|
<< nNextHeight << nNextHeight << key << nNextHeight << nNextHeight;
|
||||||
|
|
||||||
std::vector<uint256> claimHashes;
|
std::vector<uint256> claimHashes;
|
||||||
uint32_t finalClaimIdx = 0;
|
uint32_t finalClaimIdx = 0;
|
||||||
|
|
|
@ -326,59 +326,6 @@ BOOST_AUTO_TEST_CASE(trie_stays_consistent_test)
|
||||||
BOOST_CHECK(trie.empty());
|
BOOST_CHECK(trie.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(takeover_workaround_triggers)
|
|
||||||
{
|
|
||||||
auto& consensus = const_cast<Consensus::Params&>(Params().GetConsensus());
|
|
||||||
auto currentMax = consensus.nMaxTakeoverWorkaroundHeight;
|
|
||||||
consensus.nMaxTakeoverWorkaroundHeight = 10000;
|
|
||||||
BOOST_SCOPE_EXIT(&consensus, currentMax) { consensus.nMaxTakeoverWorkaroundHeight = currentMax; }
|
|
||||||
BOOST_SCOPE_EXIT_END
|
|
||||||
|
|
||||||
CClaimTrie trie(false, 0, 1);
|
|
||||||
CClaimTrieCacheTest cache(&trie);
|
|
||||||
|
|
||||||
insertUndoType icu, isu; claimUndoType ecu; supportUndoType esu; takeoverUndoType tut;
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
|
||||||
|
|
||||||
CClaimValue value;
|
|
||||||
value.nHeight = 1;
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("a", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("b", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("c", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("aa", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("bb", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
|
||||||
BOOST_CHECK(cache.insertSupportIntoMap("aa", CSupportValue()));
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
|
||||||
BOOST_CHECK(cache.flush());
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
|
||||||
|
|
||||||
CSupportValue temp;
|
|
||||||
CClaimValue cv;
|
|
||||||
BOOST_CHECK(cache.insertSupportIntoMap("bb", temp));
|
|
||||||
BOOST_CHECK(!cache.getInfoForName("aa", cv));
|
|
||||||
BOOST_CHECK(cache.removeSupportFromMap("aa", COutPoint()));
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.removeClaimFromTrie("aa", COutPoint()));
|
|
||||||
BOOST_CHECK(cache.removeClaimFromTrie("bb", COutPoint()));
|
|
||||||
BOOST_CHECK(cache.removeClaimFromTrie("cc", COutPoint()));
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("aa", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("bb", value));
|
|
||||||
BOOST_CHECK(cache.insertClaimIntoTrie("cc", value));
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.incrementBlock(icu, ecu, isu, esu, tut));
|
|
||||||
|
|
||||||
BOOST_CHECK(cache.getInfoForName("aa", cv));
|
|
||||||
BOOST_CHECK_EQUAL(3, cv.nValidAtHeight);
|
|
||||||
BOOST_CHECK(cache.getInfoForName("bb", cv));
|
|
||||||
BOOST_CHECK_EQUAL(3, cv.nValidAtHeight);
|
|
||||||
BOOST_CHECK(cache.getInfoForName("cc", cv));
|
|
||||||
BOOST_CHECK_EQUAL(1, cv.nValidAtHeight);
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOST_AUTO_TEST_CASE(verify_basic_serialization)
|
BOOST_AUTO_TEST_CASE(verify_basic_serialization)
|
||||||
{
|
{
|
||||||
CClaimValue cv;
|
CClaimValue cv;
|
||||||
|
|
Loading…
Reference in a new issue