Compare commits

..

35 Commits

Author SHA1 Message Date
Ed Hennis
6434d7f670 Merge branch 'develop' into ximinez/directory 2026-02-04 16:30:21 -04:00
Ed Hennis
e264176a7a Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  refactor: Add ServiceRegistry to help modularization (6222)
  fix: Deletes expired NFToken offers from ledger (5707)
  chore: Add .zed editor config directory to .gitignore (6317)
  docs: Update API changelog, add APIv2+APIv3 version documentation (6308)
  fix: Restore config changes that broke standalone mode (6301)
  chore: Add upper-case match for ARM64 in CompilationEnv (6315)
  ci: Update hashes of XRPLF/actions (6316)
  chore: Format all cmake files without comments (6294)
  chore: Add cmake-format pre-commit hook (6279)
2026-02-03 15:35:48 -05:00
Ed Hennis
705078e1c4 Fix formatting 2026-01-28 19:37:50 -05:00
Ed Hennis
d9b88a4312 Merge branch 'develop' into ximinez/directory 2026-01-28 19:06:26 -04:00
Ed Hennis
496d29d51c Merge commit '5f638f55536def0d88b970d1018a465a238e55f4' into ximinez/directory
* commit '5f638f55536def0d88b970d1018a465a238e55f4':
  chore: Set ColumnLimit to 120 in clang-format (6288)
2026-01-28 18:05:41 -05:00
Ed Hennis
9941187133 Merge commit '92046785d1fea5f9efe5a770d636792ea6cab78b' into ximinez/directory
* commit '92046785d1fea5f9efe5a770d636792ea6cab78b':
  test: Fix the `xrpl.net` unit test using async read (6241)
  ci: Upload Conan recipes for develop, release candidates, and releases (6286)
  fix: Stop embedded tests from hanging on ARM by using `atomic_flag` (6248)
  fix:  Remove DEFAULT fields that change to the default in associateAsset (6259) (6273)
  refactor: Update Boost to 1.90 (6280)
  refactor: clean up uses of `std::source_location` (6272)
  ci: Pass missing sanitizers input to actions (6266)
  ci: Properly propagate Conan credentials (6265)
  ci: Explicitly set version when exporting the Conan recipe (6264)
  ci: Use plus instead of hyphen for Conan recipe version suffix (6261)
  chore: Detect uninitialized variables in CMake files (6247)
  ci: Run on-trigger and on-pr when generate-version is modified (6257)
  refactor: Enforce 15-char limit and simplify labels for thread naming (6212)
  docs: Update Ripple Bug Bounty public key (6258)
  ci: Add missing commit hash to Conan recipe version (6256)
  fix: Include `<functional>` header in `Number.h` (6254)
  ci: Upload Conan recipe for merges into develop and commits to release (6235)
  Limit reply size on `TMGetObjectByHash` queries (6110)
  ci: remove 'master' branch as a trigger (6234)
  Improve ledger_entry lookups for fee, amendments, NUNL, and hashes (5644)
2026-01-28 18:04:05 -05:00
Ed Hennis
fa4ddfa9b8 Merge branch 'develop' into ximinez/directory 2026-01-15 13:03:51 -04:00
Ed Hennis
f254d398b1 Merge branch 'develop' into ximinez/directory 2026-01-15 12:06:10 -04:00
Ed Hennis
01ef2a1e98 Merge branch 'develop' into ximinez/directory 2026-01-13 18:19:20 -04:00
Ed Hennis
7608778a9f Merge branch 'develop' into ximinez/directory 2026-01-13 15:28:09 -04:00
Ed Hennis
69c1ade7d5 Merge branch 'develop' into ximinez/directory 2026-01-12 14:52:25 -04:00
Ed Hennis
8ad0d43744 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  fix: Inner batch transactions never have valid signatures (6069)
  chore: Change `/Zi` to `/Z7` for ccache, remove debug symbols in CI (6198)
  VaultClawback: Burn shares of an empty vault (6120)
  fix: Truncate thread name to 15 chars on Linux (5758)
  docs: Fix minor spelling issues in comments (6194)
2026-01-10 23:54:02 -05:00
Ed Hennis
039b8b90fd Merge branch 'develop' into ximinez/directory 2026-01-08 17:06:19 -04:00
Ed Hennis
b9bda49134 Merge branch 'develop' into ximinez/directory 2026-01-08 13:04:29 -04:00
Ed Hennis
69cb14c832 Merge branch 'develop' into ximinez/directory 2026-01-06 14:02:25 -05:00
Ed Hennis
2ec85c2a98 Merge branch 'develop' into ximinez/directory 2025-12-22 17:40:08 -05:00
Ed Hennis
6208a3aa9a Merge branch 'develop' into ximinez/directory 2025-12-18 20:00:00 -05:00
Ed Hennis
e70b95195b Merge branch 'develop' into ximinez/directory 2025-12-12 20:35:07 -05:00
Ed Hennis
2cc40a1647 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  refactor: Rename `ripple` namespace to `xrpl` (5982)
  refactor: Move JobQueue and related classes into xrpl.core module (6121)
  refactor: Rename `rippled` binary to `xrpld` (5983)
  refactor: rename info() to header() (6138)
  refactor: rename `LedgerInfo` to `LedgerHeader` (6136)
  refactor: clean up `RPCHelpers` (5684)
  chore: Fix docs readme and cmake (6122)
  chore: Clean up .gitignore and .gitattributes (6001)
  chore: Use updated secp256k1 recipe (6118)
2025-12-11 15:55:28 -05:00
Ed Hennis
238735d18b Merge branch 'develop' into ximinez/directory 2025-12-05 21:13:17 -05:00
Ed Hennis
e5cdeab184 Merge remote-tracking branch 'XRPLF/develop' into ximinez/directory
* XRPLF/develop:
  Implement Lending Protocol (unsupported) (5270)
2025-12-02 18:04:40 -05:00
Ed Hennis
2acb3fc306 Merge branch 'develop' into ximinez/directory 2025-12-01 14:40:53 -05:00
Ed Hennis
f3a9a9362d Merge branch 'develop' into ximinez/directory 2025-11-28 15:46:52 -05:00
Ed Hennis
91c5ad2388 Merge branch 'develop' into ximinez/directory 2025-11-27 01:49:04 -05:00
Ed Hennis
ced186ae6a Merge branch 'develop' into ximinez/directory 2025-11-26 00:25:25 -05:00
Ed Hennis
e1b5945077 Merge branch 'develop' into ximinez/directory 2025-11-25 14:55:15 -05:00
Ed Hennis
a2b4b06918 Merge branch 'develop' into ximinez/directory 2025-11-24 21:49:19 -05:00
Ed Hennis
54d528868f Merge branch 'develop' into ximinez/directory 2025-11-24 21:30:30 -05:00
Ed Hennis
6dd31bdef6 Merge branch 'develop' into ximinez/directory 2025-11-21 12:48:09 -05:00
Ed Hennis
d411e38615 Merge branch 'develop' into ximinez/directory 2025-11-18 22:51:13 -05:00
Ed Hennis
730ac9b763 Merge branch 'develop' into ximinez/directory 2025-11-15 03:08:49 -05:00
Ed Hennis
39715d6915 Merge branch 'develop' into ximinez/directory 2025-11-13 12:19:43 -05:00
Ed Hennis
fbeae82d61 Merge branch 'develop' into ximinez/directory 2025-11-12 14:13:03 -05:00
Ed Hennis
429c15ac0d Move the lambdas to be helper functions 2025-11-10 19:53:31 -05:00
Ed Hennis
9382fe1c82 rabbit hole: refactor dirAdd to find gaps in "full" directories.
- This would potentially be very expensive to implement, so don't.
- However, it might be a good start for a ledger fix option.
2025-11-10 19:53:31 -05:00
10 changed files with 125 additions and 88 deletions

View File

@@ -22,12 +22,6 @@ API version 2 is available in `rippled` version 2.0.0 and later. See [API-VERSIO
This version is supported by all `rippled` versions. For WebSocket and HTTP JSON-RPC requests, it is currently the default API version used when no `api_version` is specified.
## Unreleased
### Bugfixes
- Peer Crawler: The `port` field in `overlay.active[]` now consistently returns an integer instead of a string for outbound peers. [#6318](https://github.com/XRPLF/rippled/pull/6318)
## XRP Ledger server version 3.1.0
[Version 3.1.0](https://github.com/XRPLF/rippled/releases/tag/3.1.0) was released on Jan 27, 2026.

View File

@@ -6,7 +6,7 @@
"sqlite3/3.49.1#8631739a4c9b93bd3d6b753bac548a63%1765850149.926",
"soci/4.0.3#a9f8d773cd33e356b5879a4b0564f287%1765850149.46",
"snappy/1.1.10#968fef506ff261592ec30c574d4a7809%1765850147.878",
"secp256k1/0.7.1#3a61e95e220062ef32c48d019e9c81f7%1770306721.686",
"secp256k1/0.7.0#0fda78daa3b864deb8a2fbc083398356%1770226294.524",
"rocksdb/10.5.1#4a197eca381a3e5ae8adf8cffa5aacd0%1765850186.86",
"re2/20230301#ca3b241baec15bd31ea9187150e0b333%1765850148.103",
"protobuf/6.32.1#f481fd276fc23a33b85a3ed1e898b693%1765850161.038",

View File

@@ -32,7 +32,7 @@ class Xrpl(ConanFile):
"libarchive/3.8.1",
"nudb/2.0.9",
"openssl/3.5.5",
"secp256k1/0.7.1",
"secp256k1/0.7.0",
"soci/4.0.3",
"zlib/1.3.1",
]

View File

@@ -16,6 +16,7 @@
// Add new amendments to the top of this list.
// Keep it sorted in reverse chronological order.
XRPL_FEATURE(DefragDirectories, Supported::no, VoteBehavior::DefaultNo)
XRPL_FIX (ExpiredNFTokenOfferRemoval, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FIX (BatchInnerSigs, Supported::yes, VoteBehavior::DefaultNo)
XRPL_FEATURE(LendingProtocol, Supported::yes, VoteBehavior::DefaultNo)

View File

@@ -111,7 +111,6 @@ JSS(accounts); // in: LedgerEntry, Subscribe,
// handlers/Ledger, Unsubscribe
JSS(accounts_proposed); // in: Subscribe, Unsubscribe
JSS(action);
JSS(active); // out: OverlayImpl
JSS(acquiring); // out: LedgerRequest
JSS(address); // out: PeerImp
JSS(affected); // out: AcceptedLedgerTx
@@ -299,7 +298,6 @@ JSS(id); // websocket.
JSS(ident); // in: AccountCurrencies, AccountInfo,
// OwnerInfo
JSS(ignore_default); // in: AccountLines
JSS(in); // out: OverlayImpl
JSS(inLedger); // out: tx/Transaction
JSS(inbound); // out: PeerImp
JSS(index); // in: LedgerEntry
@@ -461,7 +459,6 @@ JSS(open_ledger_fee); // out: TxQ
JSS(open_ledger_level); // out: TxQ
JSS(oracles); // in: get_aggregate_price
JSS(oracle_document_id); // in: get_aggregate_price
JSS(out); // out: OverlayImpl
JSS(owner); // in: LedgerEntry, out: NetworkOPs
JSS(owner_funds); // in/out: Ledger, NetworkOPs, AcceptedLedgerTx
JSS(page_index);

View File

@@ -10,6 +10,14 @@ namespace xrpl {
namespace directory {
struct Gap
{
uint64_t const page;
SLE::pointer node;
uint64_t const nextPage;
SLE::pointer next;
};
std::uint64_t
createRoot(
ApplyView& view,
@@ -111,7 +119,9 @@ insertPage(
if (page == 0)
return std::nullopt;
if (!view.rules().enabled(fixDirectoryLimit) && page >= dirNodeMaxPages) // Old pages limit
{
return std::nullopt;
}
// We are about to create a new node; we'll link it to
// the chain first:
@@ -133,12 +143,8 @@ insertPage(
// it's the default.
if (page != 1)
node->setFieldU64(sfIndexPrevious, page - 1);
XRPL_ASSERT_PARTS(!nextPage, "xrpl::directory::insertPage", "nextPage has default value");
/* Reserved for future use when directory pages may be inserted in
* between two other pages instead of only at the end of the chain.
if (nextPage)
node->setFieldU64(sfIndexNext, nextPage);
*/
describe(node);
view.insert(node);
@@ -154,7 +160,7 @@ ApplyView::dirAdd(
uint256 const& key,
std::function<void(std::shared_ptr<SLE> const&)> const& describe)
{
auto root = peek(directory);
auto const root = peek(directory);
if (!root)
{
@@ -164,6 +170,42 @@ ApplyView::dirAdd(
auto [page, node, indexes] = directory::findPreviousPage(*this, directory, root);
if (rules().enabled(featureDefragDirectories))
{
// If there are more nodes than just the root, and there's no space in
// the last one, walk backwards to find one with space, or to find one
// missing.
std::optional<directory::Gap> gapPages;
while (page && indexes.size() >= dirNodeMaxEntries)
{
// Find a page with space, or a gap in pages.
auto [prevPage, prevNode, prevIndexes] = directory::findPreviousPage(*this, directory, node);
if (!gapPages && prevPage != page - 1)
gapPages.emplace(prevPage, prevNode, page, node);
page = prevPage;
node = prevNode;
indexes = prevIndexes;
}
// We looped through all the pages back to the root.
if (!page)
{
// If we found a gap, use it.
if (gapPages)
{
return directory::insertPage(
*this,
gapPages->page,
gapPages->node,
gapPages->nextPage,
gapPages->next,
key,
directory,
describe);
}
std::tie(page, node, indexes) = directory::findPreviousPage(*this, directory, root);
}
}
// If there's space, we use it:
if (indexes.size() < dirNodeMaxEntries)
{

View File

@@ -592,18 +592,20 @@ class LendingHelpers_test : public beast::unit_test::suite
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
Number const overpaymentAmount{50};
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset, loanScale, overpaymentAmount, TenthBips32(0), TenthBips32(0), managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -634,20 +636,20 @@ class LendingHelpers_test : public beast::unit_test::suite
// =========== VALIDATE STATE CHANGES ===========
BEAST_EXPECTS(
loanProperties.loanState.interestDue - newState.interestDue == 0,
loanProperites.loanState.interestDue - newState.interestDue == 0,
" interest change mismatch: expected 0, got " +
to_string(loanProperties.loanState.interestDue - newState.interestDue));
to_string(loanProperites.loanState.interestDue - newState.interestDue));
BEAST_EXPECTS(
loanProperties.loanState.managementFeeDue - newState.managementFeeDue == 0,
loanProperites.loanState.managementFeeDue - newState.managementFeeDue == 0,
" management fee change mismatch: expected 0, got " +
to_string(loanProperties.loanState.managementFeeDue - newState.managementFeeDue));
to_string(loanProperites.loanState.managementFeeDue - newState.managementFeeDue));
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
}
@@ -670,7 +672,7 @@ class LendingHelpers_test : public beast::unit_test::suite
std::uint32_t const paymentsRemaining = 10;
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset,
loanScale,
Number{50, 0},
@@ -678,15 +680,17 @@ class LendingHelpers_test : public beast::unit_test::suite
TenthBips32(10'000), // 10% overpayment fee
managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -717,21 +721,21 @@ class LendingHelpers_test : public beast::unit_test::suite
// =========== VALIDATE STATE CHANGES ===========
// With no Loan interest, interest outstanding should not change
BEAST_EXPECTS(
loanProperties.loanState.interestDue - newState.interestDue == 0,
loanProperites.loanState.interestDue - newState.interestDue == 0,
" interest change mismatch: expected 0, got " +
to_string(loanProperties.loanState.interestDue - newState.interestDue));
to_string(loanProperites.loanState.interestDue - newState.interestDue));
// With no Loan management fee, management fee due should not change
BEAST_EXPECTS(
loanProperties.loanState.managementFeeDue - newState.managementFeeDue == 0,
loanProperites.loanState.managementFeeDue - newState.managementFeeDue == 0,
" management fee change mismatch: expected 0, got " +
to_string(loanProperties.loanState.managementFeeDue - newState.managementFeeDue));
to_string(loanProperites.loanState.managementFeeDue - newState.managementFeeDue));
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
}
@@ -754,7 +758,7 @@ class LendingHelpers_test : public beast::unit_test::suite
std::uint32_t const paymentsRemaining = 10;
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset,
loanScale,
Number{50, 0},
@@ -762,15 +766,17 @@ class LendingHelpers_test : public beast::unit_test::suite
TenthBips32(0), // 0% overpayment fee
managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -806,22 +812,22 @@ class LendingHelpers_test : public beast::unit_test::suite
// =========== VALIDATE STATE CHANGES ===========
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
BEAST_EXPECTS(
actualPaymentParts.valueChange == newState.interestDue - loanProperties.loanState.interestDue,
actualPaymentParts.valueChange == newState.interestDue - loanProperites.loanState.interestDue,
" valueChange mismatch: expected " +
to_string(newState.interestDue - loanProperties.loanState.interestDue) + ", got " +
to_string(newState.interestDue - loanProperites.loanState.interestDue) + ", got " +
to_string(actualPaymentParts.valueChange));
// With no Loan management fee, management fee due should not change
BEAST_EXPECTS(
loanProperties.loanState.managementFeeDue - newState.managementFeeDue == 0,
loanProperites.loanState.managementFeeDue - newState.managementFeeDue == 0,
" management fee change mismatch: expected 0, got " +
to_string(loanProperties.loanState.managementFeeDue - newState.managementFeeDue));
to_string(loanProperites.loanState.managementFeeDue - newState.managementFeeDue));
}
void
@@ -843,7 +849,7 @@ class LendingHelpers_test : public beast::unit_test::suite
std::uint32_t const paymentsRemaining = 10;
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset,
loanScale,
Number{50, 0},
@@ -851,15 +857,17 @@ class LendingHelpers_test : public beast::unit_test::suite
TenthBips32(0), // 0% overpayment fee
managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -896,26 +904,26 @@ class LendingHelpers_test : public beast::unit_test::suite
// =========== VALIDATE STATE CHANGES ===========
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
// The change in interest is equal to the value change sans the
// overpayment interest
BEAST_EXPECTS(
actualPaymentParts.valueChange - actualPaymentParts.interestPaid ==
newState.interestDue - loanProperties.loanState.interestDue,
newState.interestDue - loanProperites.loanState.interestDue,
" valueChange mismatch: expected " +
to_string(
newState.interestDue - loanProperties.loanState.interestDue + actualPaymentParts.interestPaid) +
newState.interestDue - loanProperites.loanState.interestDue + actualPaymentParts.interestPaid) +
", got " + to_string(actualPaymentParts.valueChange));
// With no Loan management fee, management fee due should not change
BEAST_EXPECTS(
loanProperties.loanState.managementFeeDue - newState.managementFeeDue == 0,
loanProperites.loanState.managementFeeDue - newState.managementFeeDue == 0,
" management fee change mismatch: expected 0, got " +
to_string(loanProperties.loanState.managementFeeDue - newState.managementFeeDue));
to_string(loanProperites.loanState.managementFeeDue - newState.managementFeeDue));
}
void
@@ -939,7 +947,7 @@ class LendingHelpers_test : public beast::unit_test::suite
std::uint32_t const paymentsRemaining = 10;
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset,
loanScale,
Number{50, 0},
@@ -947,15 +955,17 @@ class LendingHelpers_test : public beast::unit_test::suite
TenthBips32(0), // 0% overpayment fee
managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -994,23 +1004,23 @@ class LendingHelpers_test : public beast::unit_test::suite
// =========== VALIDATE STATE CHANGES ===========
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
// Note that the management fee value change is not captured, as this
// value is not needed to correctly update the Vault state.
BEAST_EXPECTS(
(newState.managementFeeDue - loanProperties.loanState.managementFeeDue == Number{-20592, -5}),
(newState.managementFeeDue - loanProperites.loanState.managementFeeDue == Number{-20592, -5}),
" management fee change mismatch: expected " + to_string(Number{-20592, -5}) + ", got " +
to_string(newState.managementFeeDue - loanProperties.loanState.managementFeeDue));
to_string(newState.managementFeeDue - loanProperites.loanState.managementFeeDue));
BEAST_EXPECTS(
actualPaymentParts.valueChange - actualPaymentParts.interestPaid ==
newState.interestDue - loanProperties.loanState.interestDue,
newState.interestDue - loanProperites.loanState.interestDue,
" valueChange mismatch: expected " +
to_string(newState.interestDue - loanProperties.loanState.interestDue) + ", got " +
to_string(newState.interestDue - loanProperites.loanState.interestDue) + ", got " +
to_string(actualPaymentParts.valueChange - actualPaymentParts.interestPaid));
}
@@ -1033,7 +1043,7 @@ class LendingHelpers_test : public beast::unit_test::suite
std::uint32_t const paymentsRemaining = 10;
auto const periodicRate = loanPeriodicRate(loanInterestRate, paymentInterval);
auto const overpaymentComponents = computeOverpaymentComponents(
ExtendedPaymentComponents const overpaymentComponents = computeOverpaymentComponents(
asset,
loanScale,
Number{50, 0},
@@ -1041,15 +1051,17 @@ class LendingHelpers_test : public beast::unit_test::suite
TenthBips32(10'000), // 10% overpayment fee
managementFeeRate);
auto const loanProperties = computeLoanProperties(
auto const loanProperites = computeLoanProperties(
asset, loanPrincipal, loanInterestRate, paymentInterval, paymentsRemaining, managementFeeRate, loanScale);
Number const periodicPayment = loanProperites.periodicPayment;
auto const ret = tryOverpayment(
asset,
loanScale,
overpaymentComponents,
loanProperties.loanState,
loanProperties.periodicPayment,
loanProperites.loanState,
periodicPayment,
periodicRate,
paymentsRemaining,
managementFeeRate,
@@ -1089,23 +1101,23 @@ class LendingHelpers_test : public beast::unit_test::suite
BEAST_EXPECTS(
actualPaymentParts.principalPaid ==
loanProperties.loanState.principalOutstanding - newState.principalOutstanding,
loanProperites.loanState.principalOutstanding - newState.principalOutstanding,
" principalPaid mismatch: expected " +
to_string(loanProperties.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(loanProperites.loanState.principalOutstanding - newState.principalOutstanding) + ", got " +
to_string(actualPaymentParts.principalPaid));
// Note that the management fee value change is not captured, as this
// value is not needed to correctly update the Vault state.
BEAST_EXPECTS(
(newState.managementFeeDue - loanProperties.loanState.managementFeeDue == Number{-18304, -5}),
(newState.managementFeeDue - loanProperites.loanState.managementFeeDue == Number{-18304, -5}),
" management fee change mismatch: expected " + to_string(Number{-18304, -5}) + ", got " +
to_string(newState.managementFeeDue - loanProperties.loanState.managementFeeDue));
to_string(newState.managementFeeDue - loanProperites.loanState.managementFeeDue));
BEAST_EXPECTS(
actualPaymentParts.valueChange - actualPaymentParts.interestPaid ==
newState.interestDue - loanProperties.loanState.interestDue,
newState.interestDue - loanProperites.loanState.interestDue,
" valueChange mismatch: expected " +
to_string(newState.interestDue - loanProperties.loanState.interestDue) + ", got " +
to_string(newState.interestDue - loanProperites.loanState.interestDue) + ", got " +
to_string(actualPaymentParts.valueChange - actualPaymentParts.interestPaid));
}

View File

@@ -827,13 +827,8 @@ public:
// applyManifest should accept new manifests with
// higher sequence numbers
auto const seq0 = cache.sequence();
BEAST_EXPECT(cache.applyManifest(clone(s_a0)) == ManifestDisposition::accepted);
BEAST_EXPECT(cache.sequence() > seq0);
auto const seq1 = cache.sequence();
BEAST_EXPECT(cache.applyManifest(clone(s_a0)) == ManifestDisposition::stale);
BEAST_EXPECT(cache.sequence() == seq1);
BEAST_EXPECT(cache.applyManifest(clone(s_a1)) == ManifestDisposition::accepted);
BEAST_EXPECT(cache.applyManifest(clone(s_a1)) == ManifestDisposition::stale);

View File

@@ -459,10 +459,6 @@ ManifestCache::applyManifest(Manifest m)
auto masterKey = m.masterKey;
map_.emplace(std::move(masterKey), std::move(m));
// Something has changed. Keep track of it.
seq_++;
return ManifestDisposition::accepted;
}

View File

@@ -630,12 +630,12 @@ OverlayImpl::getOverlayInfo()
{
using namespace std::chrono;
Json::Value jv;
auto& av = jv[jss::active] = Json::Value(Json::arrayValue);
auto& av = jv["active"] = Json::Value(Json::arrayValue);
for_each([&](std::shared_ptr<PeerImp>&& sp) {
auto& pv = av.append(Json::Value(Json::objectValue));
pv[jss::public_key] = base64_encode(sp->getNodePublic().data(), sp->getNodePublic().size());
pv[jss::type] = sp->slot()->inbound() ? jss::in : jss::out;
pv[jss::type] = sp->slot()->inbound() ? "in" : "out";
pv[jss::uptime] = static_cast<std::uint32_t>(duration_cast<seconds>(sp->uptime()).count());
if (sp->crawl())
{
@@ -647,7 +647,7 @@ OverlayImpl::getOverlayInfo()
}
else
{
pv[jss::port] = sp->getRemoteAddress().port();
pv[jss::port] = std::to_string(sp->getRemoteAddress().port());
}
}