Add zero-confirmation support to webhooks (only) (#72)

This commit is contained in:
Lee *!* Clagett
2023-07-01 11:18:18 -04:00
committed by Lee *!* Clagett
parent f827dca8d1
commit fdbd3669a6
12 changed files with 408 additions and 32 deletions

View File

@@ -34,6 +34,7 @@
#include "wire/json/write.h"
#include "wire/msgpack.h"
#include "wire/uuid.h"
#include "wire/wrapper/defaulted.h"
namespace lws
{
@@ -126,9 +127,11 @@ namespace db
const auto payment_id = payment_bytes.empty() ?
nullptr : std::addressof(payment_bytes);
// defaulted will omit "id" and "block" when the output is in the
// txpool with no valid values.
wire::object(dest,
wire::field<0>("id", std::cref(self.spend_meta.id)),
wire::field<1>("block", self.link.height),
wire::optional_field<0>("id", wire::defaulted(std::cref(self.spend_meta.id), output_id::txpool())),
wire::optional_field<1>("block", wire::defaulted(self.link.height, block_id::txpool)),
wire::field<2>("index", self.spend_meta.index),
wire::field<3>("amount", self.spend_meta.amount),
wire::field<4>("timestamp", self.timestamp),

View File

@@ -30,6 +30,7 @@
#include <cassert>
#include <cstdint>
#include <iosfwd>
#include <limits>
#include <string>
#include <utility>
@@ -63,12 +64,19 @@ namespace db
WIRE_AS_INTEGER(account_time);
//! References a block height
enum class block_id : std::uint64_t {};
enum class block_id : std::uint64_t
{
txpool = std::uint64_t(-1) //! Represents not-yet-a-block
};
WIRE_AS_INTEGER(block_id);
//! References a global output number, as determined by the public chain
struct output_id
{
//! \return Special ID for outputs not yet in a block.
static constexpr output_id txpool() noexcept
{ return {0, std::numeric_limits<std::uint64_t>::max()}; }
std::uint64_t high; //!< Amount on public chain; rct outputs are `0`
std::uint64_t low; //!< Offset within `amount` on the public chain
};

View File

@@ -749,6 +749,42 @@ namespace db
return requests.get_value<request_info>(value);
}
expect<std::vector<webhook_value>>
storage_reader::find_webhook(webhook_key const& key, crypto::hash8 const& payment_id, cursor::webhooks cur)
{
MONERO_PRECOND(txn != nullptr);
assert(db != nullptr);
MONERO_CHECK(check_cursor(*txn, db->tables.webhooks, cur));
webhook_dupsort dup{};
static_assert(sizeof(dup.payment_id) == sizeof(payment_id), "bad memcpy");
std::memcpy(std::addressof(dup.payment_id), std::addressof(payment_id), sizeof(payment_id));
MDB_val lkey = lmdb::to_val(key);
MDB_val lvalue = lmdb::to_val(dup);
std::vector<webhook_value> result{};
int err = mdb_cursor_get(cur.get(), &lkey, &lvalue, MDB_GET_BOTH_RANGE);
for (;;)
{
if (err)
{
if (err == MDB_NOTFOUND)
break;
return {lmdb::error(err)};
}
if (webhooks.get_fixed_value<MONERO_FIELD(webhook_dupsort, payment_id)>(lvalue) != dup.payment_id)
break;
result.push_back(MONERO_UNWRAP(webhooks.get_value(lvalue)));
err = mdb_cursor_get(cur.get(), &lkey, &lvalue, MDB_NEXT_DUP);
}
return result;
}
expect<std::vector<std::pair<webhook_key, std::vector<webhook_value>>>>
storage_reader::get_webhooks(cursor::webhooks cur)
{

View File

@@ -133,6 +133,10 @@ namespace db
expect<request_info>
get_request(request type, account_address const& address, cursor::requests cur = nullptr) noexcept;
//! \return All webhook values associated with user `key` and `payment_id`.
expect<std::vector<webhook_value>>
find_webhook(webhook_key const& key, crypto::hash8 const& payment_id, cursor::webhooks cur = nullptr);
//! \return All webhooks in the DB
expect<std::vector<std::pair<webhook_key, std::vector<webhook_value>>>>
get_webhooks(cursor::webhooks cur = nullptr);