mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
JTx sign-and-submit mode support
This commit is contained in:
committed by
Miguel Portilla
parent
2d53ee4051
commit
119d5c1e47
@@ -3531,6 +3531,8 @@
|
|||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env_ss.h">
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\flags.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\flags.h">
|
||||||
|
|||||||
@@ -4005,6 +4005,9 @@
|
|||||||
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env.h">
|
||||||
<Filter>ripple\test\jtx</Filter>
|
<Filter>ripple\test\jtx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="..\..\src\ripple\test\jtx\Env_ss.h">
|
||||||
|
<Filter>ripple\test\jtx</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
<ClInclude Include="..\..\src\ripple\test\jtx\fee.h">
|
||||||
<Filter>ripple\test\jtx</Filter>
|
<Filter>ripple\test\jtx</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
|||||||
@@ -28,6 +28,7 @@
|
|||||||
#include <ripple/test/jtx/balance.h>
|
#include <ripple/test/jtx/balance.h>
|
||||||
#include <ripple/test/jtx/delivermin.h>
|
#include <ripple/test/jtx/delivermin.h>
|
||||||
#include <ripple/test/jtx/Env.h>
|
#include <ripple/test/jtx/Env.h>
|
||||||
|
#include <ripple/test/jtx/Env_ss.h>
|
||||||
#include <ripple/test/jtx/fee.h>
|
#include <ripple/test/jtx/fee.h>
|
||||||
#include <ripple/test/jtx/flags.h>
|
#include <ripple/test/jtx/flags.h>
|
||||||
#include <ripple/test/jtx/jtx_json.h>
|
#include <ripple/test/jtx/jtx_json.h>
|
||||||
|
|||||||
@@ -381,6 +381,12 @@ public:
|
|||||||
jtx::required(args...)(*this);
|
jtx::required(args...)(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Gets the TER result and `didApply` flag from a RPC Json result object.
|
||||||
|
*/
|
||||||
|
static
|
||||||
|
std::pair<TER, bool>
|
||||||
|
parseResult(Json::Value const& jr);
|
||||||
|
|
||||||
/** Submit an existing JTx.
|
/** Submit an existing JTx.
|
||||||
This calls postconditions.
|
This calls postconditions.
|
||||||
*/
|
*/
|
||||||
@@ -388,6 +394,12 @@ public:
|
|||||||
void
|
void
|
||||||
submit (JTx const& jt);
|
submit (JTx const& jt);
|
||||||
|
|
||||||
|
/** Use the submit RPC command with a provided JTx object.
|
||||||
|
This calls postconditions.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sign_and_submit(JTx const& jt, Json::Value params = Json::nullValue);
|
||||||
|
|
||||||
/** Check expected postconditions
|
/** Check expected postconditions
|
||||||
of JTx submission.
|
of JTx submission.
|
||||||
*/
|
*/
|
||||||
@@ -407,8 +419,7 @@ public:
|
|||||||
template <class JsonValue,
|
template <class JsonValue,
|
||||||
class... FN>
|
class... FN>
|
||||||
void
|
void
|
||||||
operator()(JsonValue&& jv,
|
operator()(JsonValue&& jv, FN const&... fN)
|
||||||
FN const&... fN)
|
|
||||||
{
|
{
|
||||||
apply(std::forward<
|
apply(std::forward<
|
||||||
JsonValue>(jv), fN...);
|
JsonValue>(jv), fN...);
|
||||||
@@ -433,6 +444,20 @@ public:
|
|||||||
std::shared_ptr<STObject const>
|
std::shared_ptr<STObject const>
|
||||||
meta();
|
meta();
|
||||||
|
|
||||||
|
/** Return the tx data for the last JTx.
|
||||||
|
|
||||||
|
Effects:
|
||||||
|
|
||||||
|
The tx data for the last transaction
|
||||||
|
ID, if any, is returned. No side
|
||||||
|
effects.
|
||||||
|
|
||||||
|
@note Only necessary for JTx submitted
|
||||||
|
with via sign-and-submit method.
|
||||||
|
*/
|
||||||
|
std::shared_ptr<STTx const>
|
||||||
|
tx() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void
|
void
|
||||||
fund (bool setDefaultRipple,
|
fund (bool setDefaultRipple,
|
||||||
|
|||||||
86
src/ripple/test/jtx/Env_ss.h
Normal file
86
src/ripple/test/jtx/Env_ss.h
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of rippled: https://github.com/ripple/rippled
|
||||||
|
Copyright (c) 2012, 2013 Ripple Labs Inc.
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
|
copyright notice and this permission notice appear in all copies.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#ifndef RIPPLE_TEST_JTX_ENV_SS_H_INCLUDED
|
||||||
|
#define RIPPLE_TEST_JTX_ENV_SS_H_INCLUDED
|
||||||
|
|
||||||
|
#include <ripple/test/jtx/Env.h>
|
||||||
|
|
||||||
|
namespace ripple {
|
||||||
|
namespace test {
|
||||||
|
namespace jtx {
|
||||||
|
|
||||||
|
/** A transaction testing environment wrapper.
|
||||||
|
Transactions submitted in sign-and-submit mode
|
||||||
|
by default.
|
||||||
|
*/
|
||||||
|
class Env_ss
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
Env& env_;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
class SignSubmitRunner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
SignSubmitRunner(SignSubmitRunner&&) = default;
|
||||||
|
SignSubmitRunner& operator= (SignSubmitRunner&&) = delete;
|
||||||
|
|
||||||
|
SignSubmitRunner(Env& env, JTx&& jt)
|
||||||
|
: env_(env)
|
||||||
|
, jt_(jt)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator()(Json::Value const& params = Json::nullValue)
|
||||||
|
{
|
||||||
|
env_.sign_and_submit(jt_, params);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Env& env_;
|
||||||
|
JTx const jt_;
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
Env_ss (Env_ss const&) = delete;
|
||||||
|
Env_ss& operator= (Env_ss const&) = delete;
|
||||||
|
|
||||||
|
Env_ss (Env& env)
|
||||||
|
: env_(env)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class JsonValue,
|
||||||
|
class... FN>
|
||||||
|
SignSubmitRunner
|
||||||
|
operator()(JsonValue&& jv, FN const&... fN)
|
||||||
|
{
|
||||||
|
auto jtx = env_.jt(std::forward<
|
||||||
|
JsonValue>(jv), fN...);
|
||||||
|
return SignSubmitRunner(env_, std::move(jtx));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // jtx
|
||||||
|
} // test
|
||||||
|
} // ripple
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -345,6 +345,20 @@ Env::trust (STAmount const& amount,
|
|||||||
test.expect(balance(account) == start);
|
test.expect(balance(account) == start);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::pair<TER, bool>
|
||||||
|
Env::parseResult(Json::Value const& jr)
|
||||||
|
{
|
||||||
|
TER ter;
|
||||||
|
if (jr.isObject() && jr.isMember(jss::result) &&
|
||||||
|
jr[jss::result].isMember(jss::engine_result_code))
|
||||||
|
ter = static_cast<TER>(
|
||||||
|
jr[jss::result][jss::engine_result_code].asInt());
|
||||||
|
else
|
||||||
|
ter = temINVALID;
|
||||||
|
return std::make_pair(ter,
|
||||||
|
isTesSuccess(ter) || isTecClaim(ter));
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Env::submit (JTx const& jt)
|
Env::submit (JTx const& jt)
|
||||||
{
|
{
|
||||||
@@ -355,12 +369,8 @@ Env::submit (JTx const& jt)
|
|||||||
Serializer s;
|
Serializer s;
|
||||||
jt.stx->add(s);
|
jt.stx->add(s);
|
||||||
auto const jr = rpc("submit", strHex(s.slice()));
|
auto const jr = rpc("submit", strHex(s.slice()));
|
||||||
if (jr["result"].isMember("engine_result_code"))
|
|
||||||
ter_ = static_cast<TER>(
|
std::tie(ter_, didApply) = parseResult(jr);
|
||||||
jr["result"]["engine_result_code"].asInt());
|
|
||||||
else
|
|
||||||
ter_ = temINVALID;
|
|
||||||
didApply = isTesSuccess(ter_) || isTecClaim(ter_);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -372,6 +382,46 @@ Env::submit (JTx const& jt)
|
|||||||
return postconditions(jt, ter_, didApply);
|
return postconditions(jt, ter_, didApply);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Env::sign_and_submit(JTx const& jt, Json::Value params)
|
||||||
|
{
|
||||||
|
bool didApply;
|
||||||
|
|
||||||
|
auto const account =
|
||||||
|
lookup(jt.jv[jss::Account].asString());
|
||||||
|
auto const& passphrase = account.name();
|
||||||
|
|
||||||
|
Json::Value jr;
|
||||||
|
if (params.isNull())
|
||||||
|
{
|
||||||
|
// Use the command line interface
|
||||||
|
auto const jv = boost::lexical_cast<std::string>(jt.jv);
|
||||||
|
jr = rpc("submit", passphrase, jv);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Use the provided parameters, and go straight
|
||||||
|
// to the (RPC) client.
|
||||||
|
assert(params.isObject());
|
||||||
|
if (!params.isMember(jss::secret) &&
|
||||||
|
!params.isMember(jss::key_type) &&
|
||||||
|
!params.isMember(jss::seed) &&
|
||||||
|
!params.isMember(jss::seed_hex) &&
|
||||||
|
!params.isMember(jss::passphrase))
|
||||||
|
{
|
||||||
|
params[jss::secret] = passphrase;
|
||||||
|
}
|
||||||
|
params[jss::tx_json] = jt.jv;
|
||||||
|
jr = client().invoke("submit", params);
|
||||||
|
}
|
||||||
|
txid_.SetHex(
|
||||||
|
jr[jss::result][jss::tx_json][jss::hash].asString());
|
||||||
|
|
||||||
|
std::tie(ter_, didApply) = parseResult(jr);
|
||||||
|
|
||||||
|
return postconditions(jt, ter_, didApply);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Env::postconditions(JTx const& jt, TER ter, bool didApply)
|
Env::postconditions(JTx const& jt, TER ter, bool didApply)
|
||||||
{
|
{
|
||||||
@@ -404,6 +454,12 @@ Env::meta()
|
|||||||
return item.second;
|
return item.second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<STTx const>
|
||||||
|
Env::tx() const
|
||||||
|
{
|
||||||
|
return current()->txRead(txid_).first;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Env::autofill_sig (JTx& jt)
|
Env::autofill_sig (JTx& jt)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <ripple/test/jtx.h>
|
#include <ripple/test/jtx.h>
|
||||||
#include <ripple/json/to_string.h>
|
#include <ripple/json/to_string.h>
|
||||||
#include <ripple/protocol/Feature.h>
|
#include <ripple/protocol/Feature.h>
|
||||||
|
#include <ripple/protocol/JsonFields.h>
|
||||||
#include <ripple/protocol/TxFlags.h>
|
#include <ripple/protocol/TxFlags.h>
|
||||||
#include <ripple/beast/hash/uhash.h>
|
#include <ripple/beast/hash/uhash.h>
|
||||||
#include <ripple/beast/unit_test.h>
|
#include <ripple/beast/unit_test.h>
|
||||||
@@ -578,6 +579,54 @@ public:
|
|||||||
env (jt);
|
env (jt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void testSignAndSubmit()
|
||||||
|
{
|
||||||
|
using namespace jtx;
|
||||||
|
Env env(*this);
|
||||||
|
Env_ss envs(env);
|
||||||
|
|
||||||
|
auto const alice = Account("alice");
|
||||||
|
env.fund(XRP(10000), alice);
|
||||||
|
|
||||||
|
{
|
||||||
|
envs(noop(alice), fee(none), seq(none))();
|
||||||
|
|
||||||
|
// Make sure we get the right account back.
|
||||||
|
auto tx = env.tx();
|
||||||
|
if (expect(tx))
|
||||||
|
{
|
||||||
|
expect(tx->getAccountID(sfAccount) == alice.id());
|
||||||
|
expect(tx->getTxnType() == ttACCOUNT_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto params = Json::Value(Json::nullValue);
|
||||||
|
envs(noop(alice), fee(none), seq(none))(params);
|
||||||
|
|
||||||
|
// Make sure we get the right account back.
|
||||||
|
auto tx = env.tx();
|
||||||
|
if (expect(tx))
|
||||||
|
{
|
||||||
|
expect(tx->getAccountID(sfAccount) == alice.id());
|
||||||
|
expect(tx->getTxnType() == ttACCOUNT_SET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto params = Json::Value(Json::objectValue);
|
||||||
|
// Force the factor low enough to fail
|
||||||
|
params[jss::fee_mult_max] = 1;
|
||||||
|
params[jss::fee_div_max] = 2;
|
||||||
|
// RPC errors result in temINVALID
|
||||||
|
envs(noop(alice), fee(none),
|
||||||
|
seq(none), ter(temINVALID))(params);
|
||||||
|
|
||||||
|
auto tx = env.tx();
|
||||||
|
expect(!tx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
run()
|
run()
|
||||||
{
|
{
|
||||||
@@ -598,6 +647,7 @@ public:
|
|||||||
testClose();
|
testClose();
|
||||||
testPath();
|
testPath();
|
||||||
testResignSigned();
|
testResignSigned();
|
||||||
|
testSignAndSubmit();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user