Implement enhanced Ticket support:

Tickets are a mechanism to allow for the "out-of-order" execution of
transactions on the XRP Ledger.

This commit, if merged, reworks the existing support for tickets and
introduces support for 'ticket batching', completing the feature set
needed for tickets.

The code is gated under the newly-introduced `TicketBatch` amendment
and the `Tickets` amendment, which is not presently active on the
network, is being removed.

The specification for this change can be found at:
https://github.com/xrp-community/standards-drafts/issues/16
This commit is contained in:
Scott Schurr
2018-10-18 18:43:02 -07:00
committed by Nik Bougalis
parent 01bd5a2646
commit 7724cca384
101 changed files with 6337 additions and 2287 deletions

View File

@@ -480,20 +480,15 @@ public:
{
using namespace jtx;
// create syntax
ticket::create("alice", "bob");
ticket::create("alice", 60);
ticket::create("alice", "bob", 60);
ticket::create("alice", 60, "bob");
ticket::create("alice", 1);
{
Env env(*this, supported_amendments().set(featureTickets));
Env env(*this, supported_amendments() | featureTicketBatch);
env.fund(XRP(10000), "alice");
env(noop("alice"),
require(owners("alice", 0), tickets("alice", 0)));
env(ticket::create("alice"),
env(ticket::create("alice", 1),
require(owners("alice", 1), tickets("alice", 1)));
env(ticket::create("alice"),
require(owners("alice", 2), tickets("alice", 2)));
}
}

View File

@@ -26,34 +26,22 @@ namespace jtx {
namespace ticket {
namespace detail {
Json::Value
create(
Account const& account,
boost::optional<Account> const& target,
boost::optional<std::uint32_t> const& expire)
create(Account const& account, std::uint32_t count)
{
Json::Value jv;
jv[jss::Account] = account.human();
jv[jss::TransactionType] = jss::TicketCreate;
if (expire)
jv["Expiration"] = *expire;
if (target)
jv["Target"] = target->human();
jv[sfTicketCount.jsonName] = count;
return jv;
}
} // namespace detail
Json::Value
cancel(Account const& account, std::string const& ticketId)
void
use::operator()(Env&, JTx& jt) const
{
Json::Value jv;
jv[jss::TransactionType] = jss::TicketCancel;
jv[jss::Account] = account.human();
jv["TicketID"] = ticketId;
return jv;
jt.fill_seq = false;
jt[sfSequence.jsonName] = 0u;
jt[sfTicketSequence.jsonName] = ticketSeq_;
}
} // namespace ticket

View File

@@ -39,62 +39,24 @@ namespace jtx {
/** Ticket operations */
namespace ticket {
namespace detail {
/** Create one of more tickets */
Json::Value
create(
Account const& account,
boost::optional<Account> const& target,
boost::optional<std::uint32_t> const& expire);
create(Account const& account, std::uint32_t count);
inline void
create_arg(
boost::optional<Account>& opt,
boost::optional<std::uint32_t>&,
Account const& value)
/** Set a ticket sequence on a JTx. */
class use
{
opt = value;
}
private:
std::uint32_t ticketSeq_;
inline void
create_arg(
boost::optional<Account>&,
boost::optional<std::uint32_t>& opt,
std::uint32_t value)
{
opt = value;
}
public:
use(std::uint32_t ticketSeq) : ticketSeq_{ticketSeq}
{
}
template <class Arg, class... Args>
void
create_args(
boost::optional<Account>& account_opt,
boost::optional<std::uint32_t>& expire_opt,
Arg const& arg,
Args const&... args)
{
create_arg(account_opt, expire_opt, arg);
if constexpr (sizeof...(args))
create_args(account_opt, expire_opt, args...);
}
} // namespace detail
/** Create a ticket */
template <class... Args>
Json::Value
create(Account const& account, Args const&... args)
{
boost::optional<Account> target;
boost::optional<std::uint32_t> expire;
if constexpr (sizeof...(args) > 0)
detail::create_args(target, expire, args...);
return detail::create(account, target, expire);
}
/** Cancel a ticket */
Json::Value
cancel(Account const& account, std::string const& ticketId);
void
operator()(Env&, JTx& jt) const;
};
} // namespace ticket