-
Notifications
You must be signed in to change notification settings - Fork 1.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Advance ripple.app.rdb #3965
Advance ripple.app.rdb #3965
Conversation
@manojsdoshi Let's run CI on this after the review has wrapped up but before merge, because a lot of this Postgres code is not unit tested. Need to make sure we didn't break anything. |
40f18f1
to
c887f80
Compare
c887f80
to
683dafd
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good. I left a couple of minor comments, but I won't need to re-review once they're addressed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry I took so long getting through this code review.
The changes look good. I pointed out a number of things that, in my opinion, could be improved. But I think most of the issues I've pointed out were already in the various files.
I'm open to discussing any of the suggestions I made.
In total this looks like a substantial improvement on the current situation. Thanks.
src/ripple/app/ledger/Ledger.cpp
Outdated
@@ -927,8 +927,7 @@ saveValidatedLedger( | |||
return true; | |||
} | |||
|
|||
auto res = dynamic_cast<RelationalDBInterfaceSqlite*>( | |||
&app.getRelationalDBInterface()) | |||
auto res = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You have a couple of choices here. A failed dynamic_cast
returns a nullptr
. But you're not checking for a nullptr
, and indirecting through a nullptr
will immediately crash the server.
A dynamic_cast
is expensive. So if you're not going to take advantage of the returned nullptr
it makes more sense to use a static_cast
, which is cheaper and will also work in the successful case. A failed static_cast
will certainly blow up as spectacularly in the failing case, but not in as predictable a fashion.
Personally, I'd be inclined to stick with the dynamic_cast
, but check the return value for nullptr
before proceeding. However if there's some way that you can guarantee to me that an SQLiteDatabase
is the only possible return value forever and for always, then the static_cast
could make sense. But in that case you should leave a comment about why the static_cast
is always safe.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/ripple/app/ledger/Ledger.cpp
Outdated
auto nodestoreHashes = | ||
dynamic_cast<PostgresDatabase*>(&app.getRelationalDatabase()) | ||
->getTxHashes(ledger.info().seq); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/ripple/app/main/Application.cpp
Outdated
@@ -1021,8 +1021,7 @@ class ApplicationImp : public Application, public BasicApp | |||
ledgerCleaner_->stop(); | |||
if (reportingETL_) | |||
reportingETL_->stop(); | |||
if (auto pg = dynamic_cast<RelationalDBInterfacePostgres*>( | |||
&*mRelationalDBInterface)) | |||
if (auto pg = dynamic_cast<PostgresDatabase*>(&*mRelationalDatabase)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FWIW, here's an example of properly checking the return value of a dynamic_cast
.
src/ripple/app/main/DBInit.h
Outdated
@@ -72,12 +72,22 @@ inline constexpr std::array<char const*, 5> LgrDBInit{ | |||
// Transaction database holds transactions and public keys | |||
inline constexpr auto TxDBName{"transaction.db"}; | |||
|
|||
inline constexpr std::array TxDBPragma | |||
// Omitting the explicit template parameters | |||
// seemed to caused undefined behaviour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd change this comment to "In C++17 omitting the explicit template parameters caused a crash."
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
src/ripple/app/main/DBInit.h
Outdated
@@ -117,12 +127,22 @@ inline constexpr std::array<char const*, 8> TxDBInit{ | |||
// The Ledger Meta database maps ledger hashes to shard indexes | |||
inline constexpr auto LgrMetaDBName{"ledger_meta.db"}; | |||
|
|||
inline constexpr std::array LgrMetaDBPragma | |||
// Omitting the explicit template parameters | |||
// seemed to caused undefined behaviour |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See the above comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -305,16 +305,16 @@ doAccountTxHelp(RPC::Context& context, AccountTxArgs const& args) | |||
{ | |||
if (args.forward) | |||
{ | |||
auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>( | |||
&context.app.getRelationalDBInterface()) | |||
auto [tx, marker] = dynamic_cast<SQLiteDatabase*>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
->oldestAccountTxPage(options); | ||
result.transactions = tx; | ||
result.marker = marker; | ||
} | ||
else | ||
{ | ||
auto [tx, marker] = dynamic_cast<RelationalDBInterfaceSqlite*>( | ||
&context.app.getRelationalDBInterface()) | ||
auto [tx, marker] = dynamic_cast<SQLiteDatabase*>( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
@@ -75,22 +75,19 @@ getCountsJson(Application& app, int minObjectCount) | |||
|
|||
if (!app.config().reporting() && app.config().useTxTables()) | |||
{ | |||
auto dbKB = dynamic_cast<RelationalDBInterfaceSqlite*>( | |||
&app.getRelationalDBInterface()) | |||
auto dbKB = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
->getKBUsedAll(); | ||
|
||
if (dbKB > 0) | ||
ret[jss::dbKBTotal] = dbKB; | ||
|
||
dbKB = dynamic_cast<RelationalDBInterfaceSqlite*>( | ||
&app.getRelationalDBInterface()) | ||
dbKB = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice job getting rid of the dynamic_cast
altogether!
->getKBUsedLedger(); | ||
|
||
if (dbKB > 0) | ||
ret[jss::dbKBLedger] = dbKB; | ||
|
||
dbKB = dynamic_cast<RelationalDBInterfaceSqlite*>( | ||
&app.getRelationalDBInterface()) | ||
dbKB = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See earlier comment about checking the return value of a dynamic_cast
for nullptr
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
8622163
to
d268183
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 Changes look good to me. You should consider removing the unused method either in this pull request or a future pull request. But that change is not worth holding up this pull request.
d268183
to
78f1539
Compare
78f1539
to
edc0572
Compare
Rebased to |
src/ripple/app/ledger/Ledger.cpp
Outdated
auto const res = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase()) | ||
->saveValidatedLedger(ledger, current); | ||
|
||
if (!res) | ||
Throw<std::runtime_error>("Failed to get relational database"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This doesn't look right. You're checking the result of saveValidatedLedger
, which would not justify a throw with this message. I think what you're going for is:
auto const db = dynamic_cast<SQLiteDatabase*>(&app.getRelationalDatabase());
if (!db)
Throw<std::runtime_error>("Failed to get relational database");
auto const res = db->saveValidatedLedger(ledger, current);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch. Done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nicely done!
This commit addresses minor bugs introduced with commit 6faaa91: - The number of threads used by the database engine was incorrectly clamped to the lower possible value, such that the database was effectively operating in single threaded mode. - The number of requests to extract at once was so high that it could result in increased latency. The bundle size is now limited to 4 and can be adjusted by a new configuration option `rq_bundle` in the `[node_db]` stanza. This is an advanced tunable and adjusting it should not be needed.
Several hard-coded parameters control the behavior of the ledger acquisition engine. The values of many of these parameters where set by intuition and have complex and non-intuitive interactions with each other and other parts of the code. An earlier commit attempted to adjust several of these parameters to improve syncing performance; initial testing was promising but a number of operators reported experiencing syncing and stability issues with their servers. As a result, this commit reverts parts of commit 1823506. This commit further adjusts some tunables so as to increase the aggressiveness of the ledger acquisition engine.
failing online delete healch check.
* "A path is considered invalid if and only if it enters and exits an address node through trust lines where No Ripple has been enabled for that address." (https://xrpl.org/rippling.html#specifics) * When loading trust lines for an account "Alice" which was reached via a trust line that has the No Ripple flag set on Alice's side, do not use or cache any of Alice's trust lines which have the No Ripple flag set on Alice's side. For typical "end-user" accounts, this will return no trust lines.
* Also remove an unused variable that's giving VS a problem
ba27cde
to
5dd35e5
Compare
5dd35e5
to
6760ad4
Compare
High Level Overview of Change
This pull request refactors the
ripple.app.rdb
module (the Relational Database Interface) with the goal of making it easier to use, read, and maintain, and also features updated documentation.Context of Change
This refactor improves Doxygen comments, documentation, naming, and the organization of the files in the
rdb
directory by increasing modularity.Type of Change
Test Plan
Since there aren't any substantial changes to the logic, only unit tests were conducted.
Future Tasks
This is likely the first of several iterative improvements to this module.