mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
fix fee rpc to allow tx_blob
This commit is contained in:
@@ -6,8 +6,8 @@ if (process.argv.length < 5)
|
||||
const secret = process.argv[2];
|
||||
const amount = BigInt(process.argv[3]) * 1000000n
|
||||
const dest = process.argv[4];
|
||||
|
||||
require('../utils-tests.js').TestRig('ws://localhost:6005').then(t=>
|
||||
const server = 'ws://tn4:6005'
|
||||
require('../utils-tests.js').TestRig(server).then(t=>
|
||||
{
|
||||
t.pay(secret, amount, dest).then(x=>
|
||||
{
|
||||
|
||||
@@ -48,6 +48,26 @@ module.exports = {
|
||||
console.log(acc)
|
||||
return acc
|
||||
};
|
||||
|
||||
const pay = (seed, amt, dest) =>
|
||||
{
|
||||
return new Promise((resolve, reject) =>
|
||||
{
|
||||
let wal = xrpljs.Wallet.fromSeed(seed);
|
||||
|
||||
api.submit({
|
||||
Account: wal.classicAddress,
|
||||
TransactionType: "Payment",
|
||||
Amount: ''+amt,
|
||||
Destination: dest,
|
||||
Fee: "10000"
|
||||
}, {wallet: wal}).then(x=>
|
||||
{
|
||||
assertTxnSuccess(x);
|
||||
resolve(x);
|
||||
}).catch(err);
|
||||
});
|
||||
};
|
||||
|
||||
const hookHash = fn =>
|
||||
{
|
||||
@@ -93,7 +113,8 @@ module.exports = {
|
||||
hsfNSDELETE: 2,
|
||||
hfsOVERRIDE: 1,
|
||||
hfsNSDELETE: 2,
|
||||
hookHash: hookHash
|
||||
hookHash: hookHash,
|
||||
pay: pay
|
||||
});
|
||||
}).catch(err);
|
||||
});
|
||||
|
||||
@@ -358,7 +358,7 @@ public:
|
||||
@returns a `Json objectvalue`
|
||||
*/
|
||||
Json::Value
|
||||
doRPC(Application& app) const;
|
||||
doRPC(Application& app, std::optional<FeeUnit64> hookFeeUnits = std::nullopt) const;
|
||||
|
||||
private:
|
||||
// Implementation for nextQueuableSeq(). The passed lock must be held.
|
||||
|
||||
@@ -1914,7 +1914,7 @@ TxQ::getTxs(ReadView const& view) const
|
||||
}
|
||||
|
||||
Json::Value
|
||||
TxQ::doRPC(Application& app) const
|
||||
TxQ::doRPC(Application& app, std::optional<FeeUnit64> hookFeeUnits) const
|
||||
{
|
||||
auto const view = app.openLedger().current();
|
||||
if (!view)
|
||||
@@ -1941,7 +1941,7 @@ TxQ::doRPC(Application& app) const
|
||||
levels[jss::median_level] = to_string(metrics.medFeeLevel);
|
||||
levels[jss::open_ledger_level] = to_string(metrics.openLedgerFeeLevel);
|
||||
|
||||
auto const baseFee = view->fees().base;
|
||||
auto const baseFee = view->fees().base + (hookFeeUnits ? hookFeeUnits->fee() : 0);
|
||||
auto& drops = ret[jss::drops] = Json::Value();
|
||||
|
||||
drops[jss::base_fee] =
|
||||
|
||||
@@ -32,8 +32,8 @@ namespace hook
|
||||
if (!tx.isFieldPresent(sfAccount))
|
||||
return {};
|
||||
|
||||
std::optional<AccountID> destAcc = tx.at(sfDestination);
|
||||
std::optional<AccountID> otxnAcc = tx.at(sfAccount);
|
||||
std::optional<AccountID> destAcc = tx.at(~sfDestination);
|
||||
std::optional<AccountID> otxnAcc = tx.at(~sfAccount);
|
||||
|
||||
if (!otxnAcc)
|
||||
return {};
|
||||
@@ -183,7 +183,7 @@ namespace hook
|
||||
for (auto& [a, e] : tshEntries)
|
||||
ret[e.first] = std::pair<AccountID, bool>{a, e.second};
|
||||
|
||||
return std::move(ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,62 +27,73 @@
|
||||
#include <ripple/rpc/GRPCHandlers.h>
|
||||
#include <ripple/app/tx/applyHook.h>
|
||||
#include <ripple/app/tx/impl/Transactor.h>
|
||||
#include <ripple/basics/FeeUnits.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
inline
|
||||
std::optional<FeeUnit64>
|
||||
getHookFees(RPC::JsonContext const& context)
|
||||
{
|
||||
auto const& params(context.params);
|
||||
if (params.isMember(jss::tx_blob))
|
||||
{
|
||||
auto ret = strUnHex(context.params[jss::tx_blob].asString());
|
||||
|
||||
if (!ret || !ret->size())
|
||||
throw std::invalid_argument("Invalid tx_blob");
|
||||
|
||||
SerialIter sitTrans(makeSlice(*ret));
|
||||
|
||||
std::unique_ptr<STTx const> stpTrans;
|
||||
stpTrans = std::make_unique<STTx const>(std::ref(sitTrans));
|
||||
|
||||
if (!stpTrans->isFieldPresent(sfAccount))
|
||||
throw std::invalid_argument("No sfAccount specified");
|
||||
|
||||
FeeUnit64 hookFees =
|
||||
Transactor::calculateHookChainFee(*(context.app.openLedger().current()),
|
||||
*stpTrans, keylet::hook(stpTrans->getAccountID(sfAccount)));
|
||||
|
||||
auto const view = context.app.openLedger().current();
|
||||
|
||||
std::vector<std::pair<AccountID, bool>> tsh =
|
||||
hook::getTransactionalStakeHolders(*stpTrans, *view);
|
||||
|
||||
for (auto const& [tshAccount, canRollback] : tsh)
|
||||
if (canRollback)
|
||||
hookFees +=
|
||||
Transactor::calculateHookChainFee(*view, *stpTrans, keylet::hook(tshAccount));
|
||||
return hookFees;
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
Json::Value
|
||||
doFee(RPC::JsonContext& context)
|
||||
{
|
||||
Json::Value jvResult = context.app.getTxQ().doRPC(context.app);
|
||||
if (jvResult.type() == Json::objectValue)
|
||||
// get hook fees, if any
|
||||
std::optional<FeeUnit64> hookFees;
|
||||
try
|
||||
{
|
||||
auto const& params(context.params);
|
||||
if (params.isMember(jss::tx_blob))
|
||||
{
|
||||
auto ret = strUnHex(context.params[jss::tx_blob].asString());
|
||||
|
||||
if (!ret || !ret->size())
|
||||
return rpcError(rpcINVALID_PARAMS);
|
||||
|
||||
SerialIter sitTrans(makeSlice(*ret));
|
||||
|
||||
std::unique_ptr<STTx const> stpTrans;
|
||||
try
|
||||
{
|
||||
stpTrans = std::make_unique<STTx const>(std::ref(sitTrans));
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
jvResult[jss::error] = "invalidTransaction";
|
||||
jvResult[jss::error_exception] = e.what();
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
if (!stpTrans->isFieldPresent(sfAccount))
|
||||
{
|
||||
jvResult[jss::error] = "invalidTransaction";
|
||||
jvResult[jss::error_exception] = "No sfAccount specified";
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
FeeUnit64 hookFees =
|
||||
Transactor::calculateHookChainFee(*(context.app.openLedger().current()),
|
||||
*stpTrans, keylet::hook(stpTrans->getAccountID(sfAccount)));
|
||||
|
||||
auto const view = context.app.openLedger().current();
|
||||
|
||||
std::vector<std::pair<AccountID, bool>> tsh =
|
||||
hook::getTransactionalStakeHolders(*stpTrans, *view);
|
||||
|
||||
for (auto const& [tshAccount, canRollback] : tsh)
|
||||
if (canRollback)
|
||||
hookFees +=
|
||||
Transactor::calculateHookChainFee(*view, *stpTrans, keylet::hook(tshAccount));
|
||||
|
||||
jvResult[jss::fee_hooks_feeunits] = to_string(hookFees.value());
|
||||
}
|
||||
|
||||
hookFees = getHookFees(context);
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
Json::Value jvResult;
|
||||
jvResult[jss::error] = "invalidTransaction";
|
||||
jvResult[jss::error_exception] = e.what();
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
Json::Value jvResult = context.app.getTxQ().doRPC(context.app, hookFees);
|
||||
if (jvResult.type() == Json::objectValue && hookFees)
|
||||
{
|
||||
jvResult[jss::fee_hooks_feeunits] = to_string(*hookFees);
|
||||
return jvResult;
|
||||
}
|
||||
|
||||
assert(false);
|
||||
RPC::inject_error(rpcINTERNAL, context.params);
|
||||
return context.params;
|
||||
|
||||
Reference in New Issue
Block a user