The Rippled codebase is large, complex, and can be intimidating for new developers. With hundreds of files, thousands of classes, and millions of lines of code, knowing how to navigate efficiently is crucial for productivity. This guide teaches you the skills to quickly locate functionality, understand code organization, and become proficient in exploring the Rippled source code.
Whether you're tracking down a bug, implementing a new feature, or simply trying to understand how something works, mastering codebase navigation will dramatically accelerate your development workflow and deepen your understanding of the XRP Ledger protocol.
void analyzeAccount(ReadView const& view, AccountID const& id)
{
// Can only read, cannot modify
auto const sle = view.read(keylet::account(id));
// Safe for concurrent access
auto balance = (*sle)[sfBalance];
}
TER modifyAccount(ApplyView& view, AccountID const& id)
{
// Can read and modify
auto sle = view.peek(keylet::account(id));
if (!sle)
return tecNO_ACCOUNT;
// Modify
(*sle)[sfBalance] = newBalance;
(*sle)[sfSequence] = (*sle)[sfSequence] + 1;
// Commit changes
view.update(sle);
return tesSUCCESS;
}
// Required field (asserts if missing)
auto const account = tx[sfAccount];
// Optional field (returns std::optional)
auto const destTag = tx[~sfDestinationTag];
if (destTag)
useDestinationTag(*destTag);
// Optional with default
auto const flags = tx[~sfFlags].value_or(0);
// In LedgerMaster.h
class LedgerMaster
{
public:
// Public interface - what can be called
std::shared_ptr<Ledger const> getValidatedLedger();
std::shared_ptr<Ledger const> getClosedLedger();
void addValidatedLedger(std::shared_ptr<Ledger const> const& ledger);
// ...
private:
// Implementation details - how it works
std::shared_ptr<Ledger> mCurrentLedger;
std::shared_ptr<Ledger> mClosedLedger;
// ...
};
// Example: Following a payment
void NetworkOPs::submitTransaction(STTx const& tx)
{
// 1. Initial validation
auto const result = checkTransaction(tx);
if (!isTesSuccess(result))
return;
// 2. Apply to open ledger
app_.openLedger().modify([&](OpenView& view)
{
return Transactor::apply(app_, view, tx); // → Go here
});
// 3. Broadcast
app_.overlay().relay(tx); // → And here
}
TER Payment::doApply()
{
// Key decision: XRP or issued currency?
if (isXRP(amount_))
{
// XRP path
return payXRP();
}
else
{
// Issued currency path
return payIssued();
}
}
cd rippled
mkdir build && cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
/**
* @brief Apply a transaction to a view
*
* @param app Application instance
* @param view Ledger view to apply to
* @param tx Transaction to apply
* @return Pair of result code and success flag
*/
std::pair<TER, bool>
applyTransaction(
Application& app,
OpenView& view,
STTx const& tx);
// Check if destination requires a tag
if (sleDest->getFlags() & lsfRequireDestTag)
{
if (!ctx.tx.isFieldPresent(sfDestinationTag))
return tecDST_TAG_NEEDED;
}