mirror of
https://github.com/XRPLF/clio.git
synced 2025-12-06 17:27:58 +00:00
@@ -124,7 +124,9 @@ AMMInfoHandler::process(AMMInfoHandler::Input input, Context const& ctx) const
|
||||
ammID = sle.getFieldH256(ripple::sfAMMID);
|
||||
}
|
||||
|
||||
auto ammKeylet = ammID != 0 ? keylet::amm(ammID) : keylet::amm(input.issue1, input.issue2);
|
||||
auto issue1 = input.issue1;
|
||||
auto issue2 = input.issue2;
|
||||
auto ammKeylet = ammID != 0 ? keylet::amm(ammID) : keylet::amm(issue1, issue2);
|
||||
auto const ammBlob = sharedPtrBackend_->fetchLedgerObject(ammKeylet.key, lgrInfo.seq, ctx.yield);
|
||||
|
||||
if (not ammBlob)
|
||||
@@ -137,8 +139,15 @@ AMMInfoHandler::process(AMMInfoHandler::Input input, Context const& ctx) const
|
||||
if (not accBlob)
|
||||
return Error{Status{RippledError::rpcACT_NOT_FOUND}};
|
||||
|
||||
// If the issue1 and issue2 are not specified, we need to get them from the AMM.
|
||||
// Otherwise we preserve the mapping of asset1 -> issue1 and asset2 -> issue2 as requested by the user.
|
||||
if (issue1 == ripple::noIssue() and issue2 == ripple::noIssue()) {
|
||||
issue1 = amm[sfAsset];
|
||||
issue2 = amm[sfAsset2];
|
||||
}
|
||||
|
||||
auto const [asset1Balance, asset2Balance] =
|
||||
getAmmPoolHolds(*sharedPtrBackend_, lgrInfo.seq, ammAccountID, amm[sfAsset], amm[sfAsset2], false, ctx.yield);
|
||||
getAmmPoolHolds(*sharedPtrBackend_, lgrInfo.seq, ammAccountID, issue1, issue2, false, ctx.yield);
|
||||
auto const lptAMMBalance = input.accountID
|
||||
? getAmmLpHolds(*sharedPtrBackend_, lgrInfo.seq, amm, *input.accountID, ctx.yield)
|
||||
: amm[sfLPTokenBalance];
|
||||
|
||||
@@ -1079,7 +1079,7 @@ TEST_F(RPCAMMInfoHandlerTest, HappyPathWithAuctionSlot)
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCAMMInfoHandlerTest, HappyPathWithAssets)
|
||||
TEST_F(RPCAMMInfoHandlerTest, HappyPathWithAssetsMatchingInputOrder)
|
||||
{
|
||||
backend->setRange(10, 30);
|
||||
|
||||
@@ -1189,3 +1189,115 @@ TEST_F(RPCAMMInfoHandlerTest, HappyPathWithAssets)
|
||||
EXPECT_EQ(output.value(), expectedResult);
|
||||
});
|
||||
}
|
||||
|
||||
TEST_F(RPCAMMInfoHandlerTest, HappyPathWithAssetsPreservesInputOrder)
|
||||
{
|
||||
backend->setRange(10, 30);
|
||||
|
||||
auto const lgrInfo = CreateLedgerInfo(LEDGERHASH, SEQ);
|
||||
auto const account1 = GetAccountIDWithString(AMM_ACCOUNT);
|
||||
auto const account2 = GetAccountIDWithString(AMM_ACCOUNT2);
|
||||
auto const issue1 = ripple::Issue(ripple::to_currency("USD"), account1);
|
||||
auto const issue2 = ripple::Issue(ripple::to_currency("JPY"), account2);
|
||||
auto const ammKeylet = ripple::keylet::amm(issue1, issue2);
|
||||
|
||||
// Note: order in the AMM object is different from the input
|
||||
auto ammObj = CreateAMMObject(AMM_ACCOUNT, "JPY", AMM_ACCOUNT, "USD", AMM_ACCOUNT2, LP_ISSUE_CURRENCY);
|
||||
auto accountRoot = CreateAccountRootObject(AMM_ACCOUNT, 0, 2, 200, 2, INDEX1, 2);
|
||||
auto const auctionIssue = ripple::Issue{ripple::Currency{LP_ISSUE_CURRENCY}, account1};
|
||||
AMMSetAuctionSlot(
|
||||
ammObj, account2, ripple::amountFromString(auctionIssue, "100"), 2, 25 * 3600, {account1, account2}
|
||||
);
|
||||
accountRoot.setFieldH256(ripple::sfAMMID, ammKeylet.key);
|
||||
|
||||
ON_CALL(*backend, fetchLedgerBySequence).WillByDefault(Return(lgrInfo));
|
||||
ON_CALL(*backend, doFetchLedgerObject(GetAccountKey(account1), testing::_, testing::_))
|
||||
.WillByDefault(Return(accountRoot.getSerializer().peekData()));
|
||||
ON_CALL(*backend, doFetchLedgerObject(GetAccountKey(account2), testing::_, testing::_))
|
||||
.WillByDefault(Return(accountRoot.getSerializer().peekData()));
|
||||
ON_CALL(*backend, doFetchLedgerObject(ammKeylet.key, testing::_, testing::_))
|
||||
.WillByDefault(Return(ammObj.getSerializer().peekData()));
|
||||
|
||||
auto static const input = json::parse(fmt::format(
|
||||
R"({{
|
||||
"asset": {{
|
||||
"currency": "USD",
|
||||
"issuer": "{}"
|
||||
}},
|
||||
"asset2": {{
|
||||
"currency": "JPY",
|
||||
"issuer": "{}"
|
||||
}}
|
||||
}})",
|
||||
AMM_ACCOUNT,
|
||||
AMM_ACCOUNT2
|
||||
));
|
||||
|
||||
auto const handler = AnyHandler{AMMInfoHandler{backend}};
|
||||
runSpawn([&](auto yield) {
|
||||
auto const output = handler.process(input, Context{yield});
|
||||
auto expectedResult = json::parse(fmt::format(
|
||||
R"({{
|
||||
"amm": {{
|
||||
"lp_token": {{
|
||||
"currency": "{}",
|
||||
"issuer": "{}",
|
||||
"value": "100"
|
||||
}},
|
||||
"amount": {{
|
||||
"currency": "{}",
|
||||
"issuer": "{}",
|
||||
"value": "0"
|
||||
}},
|
||||
"amount2": {{
|
||||
"currency": "{}",
|
||||
"issuer": "{}",
|
||||
"value": "0"
|
||||
}},
|
||||
"account": "{}",
|
||||
"trading_fee": 5,
|
||||
"auction_slot": {{
|
||||
"time_interval": 20,
|
||||
"price": {{
|
||||
"currency": "{}",
|
||||
"issuer": "{}",
|
||||
"value": "100"
|
||||
}},
|
||||
"discounted_fee": 2,
|
||||
"account": "{}",
|
||||
"expiration": "2000-01-02T01:00:00+0000",
|
||||
"auth_accounts": [
|
||||
{{
|
||||
"account": "{}"
|
||||
}},
|
||||
{{
|
||||
"account": "{}"
|
||||
}}
|
||||
]
|
||||
}},
|
||||
"asset_frozen": false,
|
||||
"asset2_frozen": false
|
||||
}},
|
||||
"ledger_index": 30,
|
||||
"ledger_hash": "{}",
|
||||
"validated": true
|
||||
}})",
|
||||
LP_ISSUE_CURRENCY,
|
||||
AMM_ACCOUNT,
|
||||
"USD",
|
||||
AMM_ACCOUNT,
|
||||
"JPY",
|
||||
AMM_ACCOUNT2,
|
||||
AMM_ACCOUNT,
|
||||
LP_ISSUE_CURRENCY,
|
||||
AMM_ACCOUNT,
|
||||
AMM_ACCOUNT2,
|
||||
AMM_ACCOUNT,
|
||||
AMM_ACCOUNT2,
|
||||
LEDGERHASH
|
||||
));
|
||||
|
||||
ASSERT_TRUE(output);
|
||||
EXPECT_EQ(output.value(), expectedResult);
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user