Fix webhook spend lookup (#240)

This commit is contained in:
Lee *!* Clagett
2026-03-25 17:16:39 -04:00
committed by Lee *!* Clagett
parent 9ee5815826
commit 466c315b11
2 changed files with 59 additions and 9 deletions
+21 -8
View File
@@ -3090,12 +3090,21 @@ namespace db
expect<void> check_spends(std::vector<webhook_tx_spend>& out, MDB_cursor& webhooks_cur, MDB_cursor& outputs_cur, const lws::account& user)
{
const account_id user_id = user.id();
const webhook_key hook_key{user_id, webhook_type::tx_spend};
MDB_val key = lmdb::to_val(hook_key);
MDB_val key = lmdb::to_val(user_id);
MDB_val value{};
int err = mdb_cursor_get(&outputs_cur, &key, &value, MDB_SET_KEY);
if (err)
{
if (err == MDB_NOTFOUND)
return success();
return log_lmdb_error(err, __LINE__, __FILE__);
}
const webhook_key hook_key{user_id, webhook_type::tx_spend};
key = lmdb::to_val(hook_key);
// Find a tx_spend for user id
int err = mdb_cursor_get(&webhooks_cur, &key, &value, MDB_SET_KEY);
err = mdb_cursor_get(&webhooks_cur, &key, &value, MDB_SET_KEY);
for (;;)
{
if (err)
@@ -3111,10 +3120,7 @@ namespace db
out.reserve(user.spends().size());
for (const spend& s : user.spends())
{
key = lmdb::to_val(user_id);
value = lmdb::to_val(s.link.height);
err = mdb_cursor_get(&outputs_cur, &key, &value, MDB_GET_BOTH_RANGE);
err = mdb_cursor_get(&outputs_cur, &key, &value, MDB_FIRST_DUP);
expect<output::spend_meta_> meta{common_error::kInvalidArgument};
for (;;)
{
@@ -3125,7 +3131,14 @@ namespace db
return meta.error();
if (meta->id == s.source)
break;
err = mdb_cursor_get(&outputs_cur, &key, &value, MDB_PREV_DUP);
const auto height = outputs.get_value<MONERO_FIELD(output, link.height)>(value);
if (!height)
return height.error();
if (s.link.height < *height)
return log_lmdb_error(MDB_NOTFOUND, __LINE__, __FILE__);
err = mdb_cursor_get(&outputs_cur, &key, &value, MDB_NEXT_DUP);
}
out.push_back(
+38 -1
View File
@@ -152,6 +152,43 @@ LWS_CASE("db::storage::*_webhook")
EXPECT(result.empty());
}
SECTION("webhooks with empty outs")
{
const boost::uuids::uuid id = boost::uuids::random_generator{}();
const boost::uuids::uuid id2 = boost::uuids::random_generator{}();
{
lws::db::webhook_value value{
lws::db::webhook_dupsort{0, id},
lws::db::webhook_data{"http://the_url_spend", "the_token_spend"}
};
lws::db::webhook_value value2{
lws::db::webhook_dupsort{0, id2},
lws::db::webhook_data{"http://the_url_spend", "the_token_spend"}
};
MONERO_UNWRAP(
db.add_webhook(lws::db::webhook_type::tx_spend, account, std::move(value))
);
MONERO_UNWRAP(
db.add_webhook(lws::db::webhook_type::tx_confirmation, account, std::move(value2))
);
}
const auto scan_height = lws::db::block_id(lmdb::to_native(last_block.id) + 1);
crypto::hash chain[2] = {
last_block.hash,
crypto::rand<crypto::hash>()
};
lws::account full_account = lws::db::test::make_account(account, view);
full_account.updated(last_block.id);
auto updated = db.update(last_block.id, chain, {std::addressof(full_account), 1}, nullptr);
EXPECT(updated.has_value());
EXPECT(updated->spend_pubs.empty());
EXPECT(updated->accounts_updated == 1);
EXPECT(updated->confirm_pubs.size() == 0);
}
SECTION("storage::update(...) one at a time")
{
lws::account full_account = lws::db::test::make_account(account, view);
@@ -436,7 +473,7 @@ LWS_CASE("db::storage::*_webhook")
EXPECT(spends.size() == 1);
const auto updated = db.update(last_block.id, chain, {std::addressof(full_account), 1}, nullptr);
EXPECT(!updated.has_error());
EXPECT(updated.error() == std::error_code{});
EXPECT(updated->accounts_updated == 1);
EXPECT(updated->confirm_pubs.size() == 3);
EXPECT(updated->spend_pubs.size() == 1);