Get Counterparty signing working

This commit is contained in:
Ed Hennis
2025-04-25 18:05:34 -04:00
parent 7823c8b186
commit 0a4c0a555d
5 changed files with 44 additions and 20 deletions

View File

@@ -59,7 +59,8 @@ class Loan_test : public beast::unit_test::suite
Env env(*this, features);
Account const alice{"alice"};
env.fund(XRP(10000), alice);
Account const bob{"bob"};
env.fund(XRP(10000), alice, bob);
auto const keylet = keylet::loanbroker(alice, env.seq(alice));
@@ -67,14 +68,16 @@ class Loan_test : public beast::unit_test::suite
using namespace loan;
// counter party signature is required on LoanSet
env(set(alice, keylet.key, Number(10000), env.now() + 720h),
auto setTx = env.jt(
set(alice, keylet.key, Number(10000), env.now() + 720h),
ter(temMALFORMED));
env(setTx);
// All loan transactions are disabled.
// 1. LoanSet
env(set(alice, keylet.key, Number(10000), env.now() + 720h),
sig(sfCounterpartySignature, alice),
ter(temDISABLED));
setTx = env.jt(
setTx, sig(sfCounterpartySignature, bob), ter(temDISABLED));
env(setTx);
auto const loanKeylet =
keylet::loan(alice.id(), keylet.key, env.seq(alice));
#if 0

View File

@@ -54,7 +54,11 @@ struct JTx
bool fill_sig = true;
bool fill_netid = true;
std::shared_ptr<STTx const> stx;
std::vector<std::function<void(Env&, JTx&)>> signers;
// Functions that sign the transaction from the Account
std::vector<std::function<void(Env&, JTx&)>> mainSigners;
// Functions that sign something else after the mainSigners, such as
// sfCounterpartySignature
std::vector<std::function<void(Env&, JTx&)>> postSigners;
JTx() = default;
JTx(JTx const&) = default;

View File

@@ -35,6 +35,7 @@
#include <xrpl/basics/Slice.h>
#include <xrpl/basics/contract.h>
#include <xrpl/basics/scope.h>
#include <xrpl/json/to_string.h>
#include <xrpl/protocol/ErrorCodes.h>
#include <xrpl/protocol/Indexes.h>
@@ -481,13 +482,25 @@ void
Env::autofill_sig(JTx& jt)
{
auto& jv = jt.jv;
if (!jt.signers.empty())
{
for (auto const& signer : jt.signers)
scope_success success([&]() {
// Call all the post-signers after the main signers or autofill are done
for (auto const& signer : jt.postSigners)
signer(*this, jt);
});
// Call all the main signers
if (!jt.mainSigners.empty())
{
for (auto const& signer : jt.mainSigners)
signer(*this, jt);
return;
}
// If the sig is still needed, get it here.
if (!jt.fill_sig)
return;
auto const account = lookup(jv[jss::Account].asString());
if (!app().checkSigs())
{
@@ -552,9 +565,8 @@ Env::st(JTx const& jt)
{
return sterilize(STTx{std::move(*obj)});
}
catch (std::exception const& e)
catch (std::exception const&)
{
test.log << e.what() << std::endl;
}
return nullptr;
}

View File

@@ -81,12 +81,9 @@ void
msig::operator()(Env& env, JTx& jt) const
{
auto const mySigners = signers;
jt.signers.emplace_back([subField = subField, mySigners, &env](
Env&, JTx& jtx) {
auto callback = [subField = subField, mySigners, &env](Env&, JTx& jtx) {
// Where to put the signature. Supports sfCounterPartySignature.
auto& sigObject = subField ? jtx[*subField] : jtx.jv;
if (jtx.fill_sig && !subField)
jtx.fill_sig = false;
sigObject[sfSigningPubKey] = "";
std::optional<STObject> st;
@@ -113,7 +110,11 @@ msig::operator()(Env& env, JTx& jt) const
jo[sfTxnSignature.getJsonName()] =
strHex(Slice{sig.data(), sig.size()});
}
});
};
if (!subField)
jt.mainSigners.emplace_back(callback);
else
jt.postSigners.emplace_back(callback);
}
} // namespace jtx

View File

@@ -29,18 +29,22 @@ sig::operator()(Env&, JTx& jt) const
{
if (!manual_)
return;
if (!subField)
jt.fill_sig = false;
if (account_)
{
// VFALCO Inefficient pre-C++14
auto const account = *account_;
jt.signers.emplace_back([subField = subField, account](Env&, JTx& jtx) {
auto callback = [subField = subField, account](Env&, JTx& jtx) {
// Where to put the signature. Supports sfCounterPartySignature.
auto& sigObject = subField ? jtx[*subField] : jtx.jv;
if (jtx.fill_sig && !subField)
jtx.fill_sig = false;
jtx::sign(jtx.jv, account, sigObject);
});
};
if (!subField)
jt.mainSigners.emplace_back(callback);
else
jt.postSigners.emplace_back(callback);
}
}