mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
sign_for RPC command fixes (RIPD-182):
o Remove warning written to log by sign_for command. o The sign_for RPC command previously only worked in the "json sign_for" form. The command now works as a straight "sign_for". The "offline" parameter also works. o Don't autofill Fee or Paths when signing offline.
This commit is contained in:
@@ -150,7 +150,7 @@ void printHelp (const po::options_description& desc)
|
|||||||
" version\n"
|
" version\n"
|
||||||
" server_info\n"
|
" server_info\n"
|
||||||
" sign <private_key> <json> [offline]\n"
|
" sign <private_key> <json> [offline]\n"
|
||||||
" sign_for\n"
|
" sign_for <signer_address> <signer_private_key> <json> [offline]\n"
|
||||||
" stop\n"
|
" stop\n"
|
||||||
" submit <tx_blob>|[<private_key> <json>]\n"
|
" submit <tx_blob>|[<private_key> <json>]\n"
|
||||||
" submit_multisigned\n"
|
" submit_multisigned\n"
|
||||||
|
|||||||
@@ -66,10 +66,6 @@ public:
|
|||||||
Transaction (
|
Transaction (
|
||||||
std::shared_ptr<STTx const> const&, std::string&, Application&) noexcept;
|
std::shared_ptr<STTx const> const&, std::string&, Application&) noexcept;
|
||||||
|
|
||||||
static
|
|
||||||
Transaction::pointer
|
|
||||||
sharedTransaction (Blob const&, Rules const& rules, Application& app);
|
|
||||||
|
|
||||||
static
|
static
|
||||||
Transaction::pointer
|
Transaction::pointer
|
||||||
transactionFromSQL (
|
transactionFromSQL (
|
||||||
|
|||||||
@@ -56,37 +56,6 @@ Transaction::Transaction (std::shared_ptr<STTx const> const& stx,
|
|||||||
mStatus = NEW;
|
mStatus = NEW;
|
||||||
}
|
}
|
||||||
|
|
||||||
Transaction::pointer Transaction::sharedTransaction (
|
|
||||||
Blob const& vucTransaction, Rules const& rules, Application& app)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
SerialIter sit (makeSlice(vucTransaction));
|
|
||||||
auto txn = std::make_shared<STTx const>(sit);
|
|
||||||
std::string reason;
|
|
||||||
auto result = std::make_shared<Transaction> (
|
|
||||||
txn, reason, app);
|
|
||||||
if (checkValidity(app.getHashRouter(),
|
|
||||||
*txn, rules, app.config()).first
|
|
||||||
!= Validity::Valid)
|
|
||||||
{
|
|
||||||
result->setStatus(INVALID);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
catch (std::exception& e)
|
|
||||||
{
|
|
||||||
JLOG (app.journal ("Ledger").warning) << "Exception constructing transaction" <<
|
|
||||||
e.what ();
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
JLOG (app.journal ("Ledger").warning) << "Exception constructing transaction";
|
|
||||||
}
|
|
||||||
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Misc.
|
// Misc.
|
||||||
//
|
//
|
||||||
|
|||||||
@@ -429,23 +429,27 @@ private:
|
|||||||
return jvRequest;
|
return jvRequest;
|
||||||
}
|
}
|
||||||
|
|
||||||
// sign_for
|
// sign_for <account> <secret> <json> offline
|
||||||
|
// sign_for <account> <secret> <json>
|
||||||
Json::Value parseSignFor (Json::Value const& jvParams)
|
Json::Value parseSignFor (Json::Value const& jvParams)
|
||||||
{
|
{
|
||||||
Json::Value txJSON;
|
bool const bOffline = 4 == jvParams.size () && jvParams[3u].asString () == "offline";
|
||||||
Json::Reader reader;
|
|
||||||
|
|
||||||
if ((4 == jvParams.size ())
|
if (3 == jvParams.size () || bOffline)
|
||||||
&& reader.parse (jvParams[3u].asString (), txJSON))
|
|
||||||
{
|
{
|
||||||
if (txJSON.type () == Json::objectValue)
|
Json::Value txJSON;
|
||||||
|
Json::Reader reader;
|
||||||
|
if (reader.parse (jvParams[2u].asString (), txJSON))
|
||||||
{
|
{
|
||||||
// Return SigningFor object for the submitted transaction.
|
// sign_for txJSON.
|
||||||
Json::Value jvRequest;
|
Json::Value jvRequest;
|
||||||
jvRequest["signing_for"] = jvParams[0u].asString ();
|
|
||||||
jvRequest["account"] = jvParams[1u].asString ();
|
jvRequest[jss::account] = jvParams[0u].asString ();
|
||||||
jvRequest["secret"] = jvParams[2u].asString ();
|
jvRequest[jss::secret] = jvParams[1u].asString ();
|
||||||
jvRequest["tx_json"] = txJSON;
|
jvRequest[jss::tx_json] = txJSON;
|
||||||
|
|
||||||
|
if (bOffline)
|
||||||
|
jvRequest[jss::offline] = true;
|
||||||
|
|
||||||
return jvRequest;
|
return jvRequest;
|
||||||
}
|
}
|
||||||
@@ -929,7 +933,7 @@ public:
|
|||||||
{ "random", &RPCParser::parseAsIs, 0, 0 },
|
{ "random", &RPCParser::parseAsIs, 0, 0 },
|
||||||
{ "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 },
|
{ "ripple_path_find", &RPCParser::parseRipplePathFind, 1, 2 },
|
||||||
{ "sign", &RPCParser::parseSignSubmit, 2, 3 },
|
{ "sign", &RPCParser::parseSignSubmit, 2, 3 },
|
||||||
{ "sign_for", &RPCParser::parseSignFor, 4, 4 },
|
{ "sign_for", &RPCParser::parseSignFor, 3, 4 },
|
||||||
{ "submit", &RPCParser::parseSignSubmit, 1, 3 },
|
{ "submit", &RPCParser::parseSignSubmit, 1, 3 },
|
||||||
{ "submit_multisigned", &RPCParser::parseSubmitMultiSigned, 1, 1 },
|
{ "submit_multisigned", &RPCParser::parseSubmitMultiSigned, 1, 1 },
|
||||||
{ "server_info", &RPCParser::parseAsIs, 0, 0 },
|
{ "server_info", &RPCParser::parseAsIs, 0, 0 },
|
||||||
|
|||||||
@@ -51,6 +51,37 @@ verify (STObject const& st,
|
|||||||
true);
|
true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Questions regarding buildMultiSigningData:
|
||||||
|
//
|
||||||
|
// Why do we include the Signer.Account in the blob to be signed?
|
||||||
|
//
|
||||||
|
// Unless you include the Account which is signing in the signing blob,
|
||||||
|
// you could swap out any Signer.Account for any other, which may also
|
||||||
|
// be on the SignerList and have a RegularKey matching the
|
||||||
|
// Signer.SigningPubKey.
|
||||||
|
//
|
||||||
|
// That RegularKey may be set to allow some 3rd party to sign transactions
|
||||||
|
// on the account's behalf, and that RegularKey could be common amongst all
|
||||||
|
// users of the 3rd party. That's just one example of sharing the same
|
||||||
|
// RegularKey amongst various accounts and just one vulnerability.
|
||||||
|
//
|
||||||
|
// "When you have something that's easy to do that makes entire classes of
|
||||||
|
// attacks clearly and obviously impossible, you need a damn good reason
|
||||||
|
// not to do it." -- David Schwartz
|
||||||
|
//
|
||||||
|
// Why would we include the signingFor account in the blob to be signed?
|
||||||
|
//
|
||||||
|
// In the current signing scheme, the account that a signer is `signing
|
||||||
|
// for/on behalf of` is the tx_json.Account.
|
||||||
|
//
|
||||||
|
// Later we might support more levels of signing. Suppose Bob is a signer
|
||||||
|
// for Alice, and Carol is a signer for Bob, so Carol can sign for Bob who
|
||||||
|
// signs for Alice. But suppose Alice has two signers: Bob and Dave. If
|
||||||
|
// Carol is a signer for both Bob and Dave, then the signature needs to
|
||||||
|
// distinguish between Carol signing for Bob and Carol signing for Dave.
|
||||||
|
//
|
||||||
|
// So, if we support multiple levels of signing, then we'll need to
|
||||||
|
// incorporate the "signing for" accounts into the signing data as well.
|
||||||
Serializer
|
Serializer
|
||||||
buildMultiSigningData (STObject const& obj, AccountID const& signingID)
|
buildMultiSigningData (STObject const& obj, AccountID const& signingID)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
#include <ripple/app/ledger/LedgerMaster.h>
|
#include <ripple/app/ledger/LedgerMaster.h>
|
||||||
#include <ripple/app/main/Application.h>
|
#include <ripple/app/main/Application.h>
|
||||||
#include <ripple/app/paths/Pathfinder.h>
|
#include <ripple/app/paths/Pathfinder.h>
|
||||||
|
#include <ripple/app/tx/apply.h> // Validity::Valid
|
||||||
#include <ripple/basics/Log.h>
|
#include <ripple/basics/Log.h>
|
||||||
#include <ripple/core/LoadFeeTrack.h>
|
#include <ripple/core/LoadFeeTrack.h>
|
||||||
#include <ripple/json/json_writer.h>
|
#include <ripple/json/json_writer.h>
|
||||||
@@ -386,7 +387,7 @@ transactionPreProcessImpl (
|
|||||||
Json::Value err = checkFee (
|
Json::Value err = checkFee (
|
||||||
params,
|
params,
|
||||||
role,
|
role,
|
||||||
signingArgs.editFields(),
|
verify && signingArgs.editFields(),
|
||||||
app.config(),
|
app.config(),
|
||||||
app.getFeeTrack(),
|
app.getFeeTrack(),
|
||||||
ledger);
|
ledger);
|
||||||
@@ -401,7 +402,7 @@ transactionPreProcessImpl (
|
|||||||
role,
|
role,
|
||||||
app,
|
app,
|
||||||
ledger,
|
ledger,
|
||||||
signingArgs.editFields());
|
verify && signingArgs.editFields());
|
||||||
|
|
||||||
if (RPC::contains_error(err))
|
if (RPC::contains_error(err))
|
||||||
return std::move (err);
|
return std::move (err);
|
||||||
@@ -427,6 +428,10 @@ transactionPreProcessImpl (
|
|||||||
tx_json[jss::Flags] = tfFullyCanonicalSig;
|
tx_json[jss::Flags] = tfFullyCanonicalSig;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If multisigning then we need to return the public key.
|
||||||
|
if (signingArgs.isMultiSigning())
|
||||||
|
signingArgs.setPublicKey (keypair.publicKey);
|
||||||
|
|
||||||
if (verify)
|
if (verify)
|
||||||
{
|
{
|
||||||
if (! sle)
|
if (! sle)
|
||||||
@@ -437,12 +442,9 @@ transactionPreProcessImpl (
|
|||||||
<< "verify: " << toBase58(calcAccountID(keypair.publicKey))
|
<< "verify: " << toBase58(calcAccountID(keypair.publicKey))
|
||||||
<< " : " << toBase58(srcAddressID);
|
<< " : " << toBase58(srcAddressID);
|
||||||
|
|
||||||
// If multisigning then we need to return the public key.
|
// Don't do this test if multisigning since the account and secret
|
||||||
if (signingArgs.isMultiSigning())
|
// probably don't belong together in that case.
|
||||||
{
|
if (!signingArgs.isMultiSigning())
|
||||||
signingArgs.setPublicKey (keypair.publicKey);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
// Make sure the account and secret belong together.
|
// Make sure the account and secret belong together.
|
||||||
error_code_i const err =
|
error_code_i const err =
|
||||||
@@ -507,7 +509,7 @@ transactionPreProcessImpl (
|
|||||||
static
|
static
|
||||||
std::pair <Json::Value, Transaction::pointer>
|
std::pair <Json::Value, Transaction::pointer>
|
||||||
transactionConstructImpl (std::shared_ptr<STTx const> const& stpTrans,
|
transactionConstructImpl (std::shared_ptr<STTx const> const& stpTrans,
|
||||||
Rules const& rules, Application& app)
|
Rules const& rules, bool validateSig, Application& app, ApplyFlags flags)
|
||||||
{
|
{
|
||||||
std::pair <Json::Value, Transaction::pointer> ret;
|
std::pair <Json::Value, Transaction::pointer> ret;
|
||||||
|
|
||||||
@@ -533,17 +535,33 @@ transactionConstructImpl (std::shared_ptr<STTx const> const& stpTrans,
|
|||||||
{
|
{
|
||||||
Serializer s;
|
Serializer s;
|
||||||
tpTrans->getSTransaction ()->add (s);
|
tpTrans->getSTransaction ()->add (s);
|
||||||
|
Blob transBlob = s.getData ();
|
||||||
|
SerialIter sit {makeSlice(transBlob)};
|
||||||
|
|
||||||
Transaction::pointer tpTransNew =
|
// Check the signature if that's called for.
|
||||||
Transaction::sharedTransaction(s.getData(), rules, app);
|
auto sttxNew = std::make_shared<STTx const> (sit);
|
||||||
|
if (validateSig &&
|
||||||
if (tpTransNew && (
|
checkValidity(app.getHashRouter(),
|
||||||
!tpTransNew->getSTransaction ()->isEquivalent (
|
*sttxNew, rules, app.config(), flags).first != Validity::Valid)
|
||||||
*tpTrans->getSTransaction ())))
|
|
||||||
{
|
{
|
||||||
tpTransNew.reset ();
|
ret.first = RPC::make_error (rpcINTERNAL,
|
||||||
|
"Invalid signature.");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string reason;
|
||||||
|
auto tpTransNew =
|
||||||
|
std::make_shared<Transaction> (sttxNew, reason, app);
|
||||||
|
|
||||||
|
if (tpTransNew)
|
||||||
|
{
|
||||||
|
if (!tpTransNew->getSTransaction()->isEquivalent (
|
||||||
|
*tpTrans->getSTransaction()))
|
||||||
|
{
|
||||||
|
tpTransNew.reset ();
|
||||||
|
}
|
||||||
|
tpTrans = std::move (tpTransNew);
|
||||||
}
|
}
|
||||||
tpTrans = std::move (tpTransNew);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception&)
|
catch (std::exception&)
|
||||||
@@ -656,7 +674,8 @@ Json::Value transactionSign (
|
|||||||
Role role,
|
Role role,
|
||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger)
|
std::shared_ptr<ReadView const> ledger,
|
||||||
|
ApplyFlags flags)
|
||||||
{
|
{
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
|
|
||||||
@@ -674,8 +693,8 @@ Json::Value transactionSign (
|
|||||||
|
|
||||||
// Make sure the STTx makes a legitimate Transaction.
|
// Make sure the STTx makes a legitimate Transaction.
|
||||||
std::pair <Json::Value, Transaction::pointer> txn =
|
std::pair <Json::Value, Transaction::pointer> txn =
|
||||||
transactionConstructImpl (preprocResult.second,
|
transactionConstructImpl (
|
||||||
ledger->rules(), app);
|
preprocResult.second, ledger->rules(), true, app, flags);
|
||||||
|
|
||||||
if (!txn.second)
|
if (!txn.second)
|
||||||
return txn.first;
|
return txn.first;
|
||||||
@@ -691,7 +710,8 @@ Json::Value transactionSubmit (
|
|||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger,
|
std::shared_ptr<ReadView const> ledger,
|
||||||
ProcessTransactionFn const& processTransaction)
|
ProcessTransactionFn const& processTransaction,
|
||||||
|
ApplyFlags flags)
|
||||||
{
|
{
|
||||||
using namespace detail;
|
using namespace detail;
|
||||||
|
|
||||||
@@ -709,8 +729,8 @@ Json::Value transactionSubmit (
|
|||||||
|
|
||||||
// Make sure the STTx makes a legitimate Transaction.
|
// Make sure the STTx makes a legitimate Transaction.
|
||||||
std::pair <Json::Value, Transaction::pointer> txn =
|
std::pair <Json::Value, Transaction::pointer> txn =
|
||||||
transactionConstructImpl (preprocResult.second,
|
transactionConstructImpl (
|
||||||
ledger->rules(), app);
|
preprocResult.second, ledger->rules(), true, app, flags);
|
||||||
|
|
||||||
if (!txn.second)
|
if (!txn.second)
|
||||||
return txn.first;
|
return txn.first;
|
||||||
@@ -735,7 +755,7 @@ namespace detail
|
|||||||
{
|
{
|
||||||
// There are a some field checks shared by transactionSignFor
|
// There are a some field checks shared by transactionSignFor
|
||||||
// and transactionSubmitMultiSigned. Gather them together here.
|
// and transactionSubmitMultiSigned. Gather them together here.
|
||||||
Json::Value checkMultiSignFields (Json::Value const& jvRequest)
|
static Json::Value checkMultiSignFields (Json::Value const& jvRequest)
|
||||||
{
|
{
|
||||||
if (! jvRequest.isMember (jss::tx_json))
|
if (! jvRequest.isMember (jss::tx_json))
|
||||||
return RPC::missing_field_error (jss::tx_json);
|
return RPC::missing_field_error (jss::tx_json);
|
||||||
@@ -767,7 +787,8 @@ Json::Value transactionSignFor (
|
|||||||
Role role,
|
Role role,
|
||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger)
|
std::shared_ptr<ReadView const> ledger,
|
||||||
|
ApplyFlags flags)
|
||||||
{
|
{
|
||||||
auto j = app.journal ("RPCHandler");
|
auto j = app.journal ("RPCHandler");
|
||||||
JLOG (j.debug) << "transactionSignFor: " << jvRequest;
|
JLOG (j.debug) << "transactionSignFor: " << jvRequest;
|
||||||
@@ -828,8 +849,8 @@ Json::Value transactionSignFor (
|
|||||||
|
|
||||||
// Make sure the STTx makes a legitimate Transaction.
|
// Make sure the STTx makes a legitimate Transaction.
|
||||||
std::pair <Json::Value, Transaction::pointer> txn =
|
std::pair <Json::Value, Transaction::pointer> txn =
|
||||||
transactionConstructImpl (preprocResult.second,
|
transactionConstructImpl (
|
||||||
ledger->rules(), app);
|
preprocResult.second, ledger->rules(), false, app, flags);
|
||||||
|
|
||||||
if (!txn.second)
|
if (!txn.second)
|
||||||
return txn.first;
|
return txn.first;
|
||||||
@@ -870,7 +891,8 @@ Json::Value transactionSubmitMultiSigned (
|
|||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger,
|
std::shared_ptr<ReadView const> ledger,
|
||||||
ProcessTransactionFn const& processTransaction)
|
ProcessTransactionFn const& processTransaction,
|
||||||
|
ApplyFlags flags)
|
||||||
{
|
{
|
||||||
auto j = app.journal ("RPCHandler");
|
auto j = app.journal ("RPCHandler");
|
||||||
JLOG (j.debug)
|
JLOG (j.debug)
|
||||||
@@ -1056,8 +1078,7 @@ Json::Value transactionSubmitMultiSigned (
|
|||||||
|
|
||||||
// Make sure the SerializedTransaction makes a legitimate Transaction.
|
// Make sure the SerializedTransaction makes a legitimate Transaction.
|
||||||
std::pair <Json::Value, Transaction::pointer> txn =
|
std::pair <Json::Value, Transaction::pointer> txn =
|
||||||
transactionConstructImpl (stpTrans,
|
transactionConstructImpl (stpTrans, ledger->rules(), true, app, flags);
|
||||||
ledger->rules(), app);
|
|
||||||
|
|
||||||
if (!txn.second)
|
if (!txn.second)
|
||||||
return txn.first;
|
return txn.first;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <ripple/app/misc/NetworkOPs.h>
|
#include <ripple/app/misc/NetworkOPs.h>
|
||||||
#include <ripple/server/Role.h>
|
#include <ripple/server/Role.h>
|
||||||
|
#include <ripple/ledger/ApplyView.h>
|
||||||
|
|
||||||
namespace ripple {
|
namespace ripple {
|
||||||
|
|
||||||
@@ -81,7 +82,8 @@ Json::Value transactionSign (
|
|||||||
Role role,
|
Role role,
|
||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger);
|
std::shared_ptr<ReadView const> ledger,
|
||||||
|
ApplyFlags flags = tapNONE);
|
||||||
|
|
||||||
/** Returns a Json::objectValue. */
|
/** Returns a Json::objectValue. */
|
||||||
Json::Value transactionSubmit (
|
Json::Value transactionSubmit (
|
||||||
@@ -91,7 +93,8 @@ Json::Value transactionSubmit (
|
|||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger,
|
std::shared_ptr<ReadView const> ledger,
|
||||||
ProcessTransactionFn const& processTransaction);
|
ProcessTransactionFn const& processTransaction,
|
||||||
|
ApplyFlags flags = tapNONE);
|
||||||
|
|
||||||
/** Returns a Json::objectValue. */
|
/** Returns a Json::objectValue. */
|
||||||
Json::Value transactionSignFor (
|
Json::Value transactionSignFor (
|
||||||
@@ -100,7 +103,8 @@ Json::Value transactionSignFor (
|
|||||||
Role role,
|
Role role,
|
||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger);
|
std::shared_ptr<ReadView const> ledger,
|
||||||
|
ApplyFlags flags = tapNONE);
|
||||||
|
|
||||||
/** Returns a Json::objectValue. */
|
/** Returns a Json::objectValue. */
|
||||||
Json::Value transactionSubmitMultiSigned (
|
Json::Value transactionSubmitMultiSigned (
|
||||||
@@ -110,7 +114,8 @@ Json::Value transactionSubmitMultiSigned (
|
|||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger,
|
std::shared_ptr<ReadView const> ledger,
|
||||||
ProcessTransactionFn const& processTransaction);
|
ProcessTransactionFn const& processTransaction,
|
||||||
|
ApplyFlags flags = tapNONE);
|
||||||
|
|
||||||
} // RPC
|
} // RPC
|
||||||
} // ripple
|
} // ripple
|
||||||
|
|||||||
@@ -557,6 +557,7 @@ R"({
|
|||||||
"secret": "masterpassphrase",
|
"secret": "masterpassphrase",
|
||||||
"offline": 1,
|
"offline": 1,
|
||||||
"tx_json": {
|
"tx_json": {
|
||||||
|
"Fee": 10,
|
||||||
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
"Amount": "1000000000",
|
"Amount": "1000000000",
|
||||||
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||||
@@ -569,7 +570,7 @@ R"({
|
|||||||
"Missing field 'tx_json.Sequence'.",
|
"Missing field 'tx_json.Sequence'.",
|
||||||
"Missing field 'tx_json.Sequence'."}},
|
"Missing field 'tx_json.Sequence'."}},
|
||||||
|
|
||||||
{ "Valid transaction if 'offline' is true.",
|
{ "If 'offline' is true then a 'Fee' field must be supplied.",
|
||||||
R"({
|
R"({
|
||||||
"command": "doesnt_matter",
|
"command": "doesnt_matter",
|
||||||
"account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
"account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
@@ -584,11 +585,54 @@ R"({
|
|||||||
}
|
}
|
||||||
})",
|
})",
|
||||||
{
|
{
|
||||||
|
"Missing field 'tx_json.Fee'.",
|
||||||
|
"Missing field 'tx_json.Fee'.",
|
||||||
|
"Missing field 'tx_json.SigningPubKey'.",
|
||||||
|
"Missing field 'tx_json.SigningPubKey'."}},
|
||||||
|
|
||||||
|
{ "Valid transaction if 'offline' is true.",
|
||||||
|
R"({
|
||||||
|
"command": "doesnt_matter",
|
||||||
|
"account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"secret": "masterpassphrase",
|
||||||
|
"offline": 1,
|
||||||
|
"tx_json": {
|
||||||
|
"Sequence": 0,
|
||||||
|
"Fee": 10,
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Amount": "1000000000",
|
||||||
|
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||||
|
"TransactionType": "Payment"
|
||||||
|
}
|
||||||
|
})",
|
||||||
|
{
|
||||||
"",
|
"",
|
||||||
"",
|
"",
|
||||||
"Missing field 'tx_json.SigningPubKey'.",
|
"Missing field 'tx_json.SigningPubKey'.",
|
||||||
"Missing field 'tx_json.SigningPubKey'."}},
|
"Missing field 'tx_json.SigningPubKey'."}},
|
||||||
|
|
||||||
|
{ "'offline' and 'build_path' are mutually exclusive.",
|
||||||
|
R"({
|
||||||
|
"command": "doesnt_matter",
|
||||||
|
"account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"secret": "masterpassphrase",
|
||||||
|
"offline": 1,
|
||||||
|
"build_path": 1,
|
||||||
|
"tx_json": {
|
||||||
|
"Sequence": 0,
|
||||||
|
"Fee": 10,
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Amount": "1000000000",
|
||||||
|
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||||
|
"TransactionType": "Payment"
|
||||||
|
}
|
||||||
|
})",
|
||||||
|
{
|
||||||
|
"Field 'build_path' not allowed in this context.",
|
||||||
|
"Field 'build_path' not allowed in this context.",
|
||||||
|
"Missing field 'tx_json.SigningPubKey'.",
|
||||||
|
"Missing field 'tx_json.SigningPubKey'."}},
|
||||||
|
|
||||||
{ "A 'Flags' field may be specified.",
|
{ "A 'Flags' field may be specified.",
|
||||||
R"({
|
R"({
|
||||||
"command": "doesnt_matter",
|
"command": "doesnt_matter",
|
||||||
@@ -667,6 +711,28 @@ R"({
|
|||||||
"",
|
"",
|
||||||
"Missing field 'tx_json.Signers'."}},
|
"Missing field 'tx_json.Signers'."}},
|
||||||
|
|
||||||
|
{ "Minimal offline sign_for.",
|
||||||
|
R"({
|
||||||
|
"command": "doesnt_matter",
|
||||||
|
"account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"secret": "masterpassphrase",
|
||||||
|
"offline": 1,
|
||||||
|
"tx_json": {
|
||||||
|
"Account": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||||
|
"Amount": "1000000000",
|
||||||
|
"Destination": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Fee": 50,
|
||||||
|
"Sequence": 0,
|
||||||
|
"SigningPubKey": "",
|
||||||
|
"TransactionType": "Payment"
|
||||||
|
}
|
||||||
|
})",
|
||||||
|
{
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"",
|
||||||
|
"Missing field 'tx_json.Signers'."}},
|
||||||
|
|
||||||
{ "Missing 'Account' in sign_for.",
|
{ "Missing 'Account' in sign_for.",
|
||||||
R"({
|
R"({
|
||||||
"command": "doesnt_matter",
|
"command": "doesnt_matter",
|
||||||
@@ -829,6 +895,34 @@ R"({
|
|||||||
"Missing field 'tx_json.TransactionType'."}},
|
"Missing field 'tx_json.TransactionType'."}},
|
||||||
|
|
||||||
{ "Minimal submit_multisigned.",
|
{ "Minimal submit_multisigned.",
|
||||||
|
R"({
|
||||||
|
"command": "submit_multisigned",
|
||||||
|
"tx_json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Amount": "1000000000",
|
||||||
|
"Destination": "rnUy2SHTrB9DubsPmkJZUXTf5FcNDGrYEA",
|
||||||
|
"Fee": 50,
|
||||||
|
"Sequence": 0,
|
||||||
|
"Signers" : [
|
||||||
|
{
|
||||||
|
"Signer" : {
|
||||||
|
"Account" : "rPcNzota6B8YBokhYtcTNqQVCngtbnWfux",
|
||||||
|
"SigningPubKey" : "02FE36A690D6973D55F88553F5D2C4202DE75F2CF8A6D0E17C70AC223F044501F8",
|
||||||
|
"TxnSignature" : "3045022100909D01399AFFAD1E30D250CE61F93975B7F61E47B5244D78C3E86D9806535D95022012E389E0ACB016334052B7FE07FA6CEFDC8BE82CB410FA841D5049641C89DC8F"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"SigningPubKey": "",
|
||||||
|
"TransactionType": "Payment"
|
||||||
|
}
|
||||||
|
})",
|
||||||
|
{
|
||||||
|
"Missing field 'secret'.",
|
||||||
|
"Missing field 'secret'.",
|
||||||
|
"Missing field 'account'.",
|
||||||
|
""}},
|
||||||
|
|
||||||
|
{ "Minimal submit_multisigned with bad signature.",
|
||||||
R"({
|
R"({
|
||||||
"command": "submit_multisigned",
|
"command": "submit_multisigned",
|
||||||
"tx_json": {
|
"tx_json": {
|
||||||
@@ -854,7 +948,7 @@ R"({
|
|||||||
"Missing field 'secret'.",
|
"Missing field 'secret'.",
|
||||||
"Missing field 'secret'.",
|
"Missing field 'secret'.",
|
||||||
"Missing field 'account'.",
|
"Missing field 'account'.",
|
||||||
""}},
|
"Invalid signature."}},
|
||||||
|
|
||||||
{ "Missing tx_json in submit_multisigned.",
|
{ "Missing tx_json in submit_multisigned.",
|
||||||
R"({
|
R"({
|
||||||
@@ -1463,7 +1557,8 @@ public:
|
|||||||
Role role,
|
Role role,
|
||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger);
|
std::shared_ptr<ReadView const> ledger,
|
||||||
|
ApplyFlags flags);
|
||||||
|
|
||||||
using submitFunc = Json::Value (*) (
|
using submitFunc = Json::Value (*) (
|
||||||
Json::Value params,
|
Json::Value params,
|
||||||
@@ -1472,7 +1567,8 @@ public:
|
|||||||
int validatedLedgerAge,
|
int validatedLedgerAge,
|
||||||
Application& app,
|
Application& app,
|
||||||
std::shared_ptr<ReadView const> ledger,
|
std::shared_ptr<ReadView const> ledger,
|
||||||
ProcessTransactionFn const& processTransaction);
|
ProcessTransactionFn const& processTransaction,
|
||||||
|
ApplyFlags flags);
|
||||||
|
|
||||||
using TestStuff =
|
using TestStuff =
|
||||||
std::tuple <signFunc, submitFunc, char const*, unsigned int>;
|
std::tuple <signFunc, submitFunc, char const*, unsigned int>;
|
||||||
@@ -1512,7 +1608,8 @@ public:
|
|||||||
testRole,
|
testRole,
|
||||||
1,
|
1,
|
||||||
env.app(),
|
env.app(),
|
||||||
ledger);
|
ledger,
|
||||||
|
tapENABLE_TESTING);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1525,7 +1622,8 @@ public:
|
|||||||
1,
|
1,
|
||||||
env.app(),
|
env.app(),
|
||||||
ledger,
|
ledger,
|
||||||
processTxn);
|
processTxn,
|
||||||
|
tapENABLE_TESTING);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string errStr;
|
std::string errStr;
|
||||||
|
|||||||
Reference in New Issue
Block a user