mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
add batch
This commit is contained in:
@@ -49,6 +49,7 @@ public:
|
||||
TER const preclaimResult;
|
||||
XRPAmount const baseFee;
|
||||
beast::Journal const journal;
|
||||
OpenView& base_;
|
||||
|
||||
ApplyView&
|
||||
view()
|
||||
@@ -139,7 +140,7 @@ private:
|
||||
XRPAmount const fee,
|
||||
std::index_sequence<Is...>);
|
||||
|
||||
OpenView& base_;
|
||||
// OpenView& base_;
|
||||
ApplyFlags flags_;
|
||||
std::optional<ApplyViewImpl> view_;
|
||||
};
|
||||
|
||||
196
src/ripple/app/tx/impl/Batch.cpp
Normal file
196
src/ripple/app/tx/impl/Batch.cpp
Normal file
@@ -0,0 +1,196 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
//==============================================================================
|
||||
|
||||
#include <ripple/app/tx/impl/ApplyContext.h>
|
||||
#include <ripple/app/tx/applySteps.h>
|
||||
#include <ripple/app/tx/impl/Batch.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/ledger/View.h>
|
||||
#include <ripple/protocol/Feature.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
#include <ripple/app/tx/impl/Invoke.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
PreclaimContext
|
||||
makePreclaimTx(PreclaimContext const& ctx, TxType const& tt, STObject const& txn)
|
||||
{
|
||||
auto const stx = STTx(tt, [&txn](STObject& obj){
|
||||
obj = std::move(txn);
|
||||
});
|
||||
PreclaimContext const pcctx(ctx.app, ctx.view, tesSUCCESS, stx, ctx.flags, ctx.j);
|
||||
return pcctx;
|
||||
}
|
||||
|
||||
TxConsequences
|
||||
Batch::makeTxConsequences(PreflightContext const& ctx)
|
||||
{
|
||||
return TxConsequences{ctx.tx, TxConsequences::normal};
|
||||
}
|
||||
|
||||
NotTEC
|
||||
Batch::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
|
||||
auto const& txns = tx.getFieldArray(sfEmittedTxns);
|
||||
if (txns.empty())
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Batch: txns array empty.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
if (txns.size() > 400)
|
||||
{
|
||||
JLOG(ctx.j.warn())
|
||||
<< "Batch: txns array exceeds 400 entries.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
for (auto const& txn : txns)
|
||||
{
|
||||
if (!txn.isFieldPresent(sfTransactionType))
|
||||
{
|
||||
JLOG(ctx.j.warn())
|
||||
<< "Batch: TransactionType missing in array entry.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
auto const tt = txn.getFieldU16(sfTransactionType);
|
||||
auto const account = txn.getAccountID(sfAccount);
|
||||
std::cout << "account: " << account << "\n";
|
||||
auto const stx = STTx(ttINVOKE, [&txn](STObject& obj){
|
||||
obj = std::move(txn);
|
||||
});
|
||||
|
||||
auto const txBlob = strHex(stx.getSerializer().slice());
|
||||
std::cout << "txBlob: " << txBlob << "\n";
|
||||
|
||||
PreflightContext const pfctx(ctx.app, stx, ctx.rules, ctx.flags, ctx.j);
|
||||
|
||||
switch (tt)
|
||||
{
|
||||
case ttINVOKE:
|
||||
std::cout << "tt: " << "ttINVOKE" << "\n";
|
||||
// DA: Create array of responses
|
||||
Invoke::preflight(pfctx);
|
||||
default:
|
||||
std::cout << "tt: " << "temUNKNOWN" << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
TER
|
||||
Batch::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
if (!ctx.view.rules().enabled(featureHooks))
|
||||
return temDISABLED;
|
||||
|
||||
auto const& txns = ctx.tx.getFieldArray(sfEmittedTxns);
|
||||
for (auto const& txn : txns)
|
||||
{
|
||||
if (!txn.isFieldPresent(sfTransactionType))
|
||||
{
|
||||
JLOG(ctx.j.warn())
|
||||
<< "Batch: TransactionType missing in array entry.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
auto const tt = txn.getFieldU16(sfTransactionType);
|
||||
|
||||
auto const stx = STTx(ttINVOKE, [&txn](STObject& obj){
|
||||
obj = std::move(txn);
|
||||
});
|
||||
PreclaimContext const pcctx(ctx.app, ctx.view, tesSUCCESS, stx, ctx.flags, ctx.j);
|
||||
|
||||
switch (tt)
|
||||
{
|
||||
case ttINVOKE:
|
||||
std::cout << "tt: " << "ttINVOKE" << "\n";
|
||||
// auto const pcctx1 = makePreclaimTx(ctx, ttINVOKE, txn);
|
||||
// DA: Create array of responses
|
||||
Invoke::preclaim(pcctx);
|
||||
break;
|
||||
default:
|
||||
std::cout << "tt: " << "temUNKNOWN" << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
Batch::doApply()
|
||||
{
|
||||
auto const& txns = ctx_.tx.getFieldArray(sfEmittedTxns);
|
||||
for (auto const& txn : txns)
|
||||
{
|
||||
if (!txn.isFieldPresent(sfTransactionType))
|
||||
{
|
||||
JLOG(ctx_.journal.warn())
|
||||
<< "Batch: TransactionType missing in array entry.";
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
auto const tt = txn.getFieldU16(sfTransactionType);
|
||||
auto const stx = STTx(ttINVOKE, [&txn](STObject& obj){
|
||||
obj = std::move(txn);
|
||||
});
|
||||
ApplyContext actx(ctx_.app, ctx_.base_, stx, tesSUCCESS, XRPAmount(1), view().flags(), ctx_.journal);
|
||||
Invoke p(actx);
|
||||
|
||||
switch (tt)
|
||||
{
|
||||
case ttINVOKE:
|
||||
std::cout << "tt: " << "ttINVOKE" << "\n";
|
||||
// DA: Create array of responses
|
||||
p();
|
||||
default:
|
||||
std::cout << "tt: " << "temUNKNOWN" << "\n";
|
||||
}
|
||||
|
||||
}
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
XRPAmount
|
||||
Batch::calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
{
|
||||
XRPAmount extraFee{0};
|
||||
// if (tx.isFieldPresent(sfEmittedTxns))
|
||||
// {
|
||||
// XRPAmount txFees{0};
|
||||
// auto const& txns = tx.getFieldArray(sfEmittedTxns);
|
||||
// for (auto const& txn : txns)
|
||||
// {
|
||||
// txFees += txn.isFieldPresent(sfFee) ? txn.getFieldAmount(sfFee) : XRPAmount{0};
|
||||
// }
|
||||
// extraFee += txFees;
|
||||
// }
|
||||
return Transactor::calculateBaseFee(view, tx) + extraFee;
|
||||
}
|
||||
|
||||
} // namespace ripple
|
||||
57
src/ripple/app/tx/impl/Batch.h
Normal file
57
src/ripple/app/tx/impl/Batch.h
Normal file
@@ -0,0 +1,57 @@
|
||||
//------------------------------------------------------------------------------
|
||||
/*
|
||||
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_TX_BATCH_H_INCLUDED
|
||||
#define RIPPLE_TX_BATCH_H_INCLUDED
|
||||
|
||||
#include <ripple/app/tx/impl/Transactor.h>
|
||||
#include <ripple/basics/Log.h>
|
||||
#include <ripple/core/Config.h>
|
||||
#include <ripple/protocol/Indexes.h>
|
||||
|
||||
namespace ripple {
|
||||
|
||||
class Batch : public Transactor
|
||||
{
|
||||
public:
|
||||
static constexpr ConsequencesFactoryType ConsequencesFactory{Custom};
|
||||
|
||||
explicit Batch(ApplyContext& ctx) : Transactor(ctx)
|
||||
{
|
||||
}
|
||||
|
||||
static XRPAmount
|
||||
calculateBaseFee(ReadView const& view, STTx const& tx);
|
||||
|
||||
static TxConsequences
|
||||
makeTxConsequences(PreflightContext const& ctx);
|
||||
|
||||
static NotTEC
|
||||
preflight(PreflightContext const& ctx);
|
||||
|
||||
static TER
|
||||
preclaim(PreclaimContext const& ctx);
|
||||
|
||||
TER
|
||||
doApply() override;
|
||||
};
|
||||
|
||||
} // namespace ripple
|
||||
|
||||
#endif
|
||||
@@ -241,6 +241,9 @@ XRPNotCreated::finalize(
|
||||
return drops_ == drops;
|
||||
}
|
||||
|
||||
if (tt == ttBATCH)
|
||||
return true;
|
||||
|
||||
// The net change should never be positive, as this would mean that the
|
||||
// transaction created XRP out of thin air. That's not possible.
|
||||
if (drops_ > 0)
|
||||
|
||||
@@ -34,24 +34,27 @@ Invoke::makeTxConsequences(PreflightContext const& ctx)
|
||||
NotTEC
|
||||
Invoke::preflight(PreflightContext const& ctx)
|
||||
{
|
||||
std::cout << "Invoke::preflight" << "\n";
|
||||
if (auto const ret = preflight1(ctx); !isTesSuccess(ret))
|
||||
return ret;
|
||||
|
||||
auto& tx = ctx.tx;
|
||||
|
||||
if (tx.getFieldVL(sfBlob).size() > (128 * 1024))
|
||||
if (tx.isFieldPresent(sfBlob) && tx.getFieldVL(sfBlob).size() > (128 * 1024))
|
||||
{
|
||||
JLOG(ctx.j.warn()) << "Invoke: blob was more than 128kib "
|
||||
<< tx.getTransactionID();
|
||||
return temMALFORMED;
|
||||
}
|
||||
|
||||
std::cout << "Invoke::preflight" << "FINISHED" << "\n";
|
||||
return preflight2(ctx);
|
||||
}
|
||||
|
||||
TER
|
||||
Invoke::preclaim(PreclaimContext const& ctx)
|
||||
{
|
||||
std::cout << "Invoke::preclaim" << "\n";
|
||||
if (!ctx.view.rules().enabled(featureHooks))
|
||||
return temDISABLED;
|
||||
|
||||
@@ -67,12 +70,14 @@ Invoke::preclaim(PreclaimContext const& ctx)
|
||||
return tecNO_TARGET;
|
||||
}
|
||||
|
||||
std::cout << "Invoke::preclaim" << "FINISHED" << "\n";
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
TER
|
||||
Invoke::doApply()
|
||||
{
|
||||
std::cout << "Invoke::doApply" << "\n";
|
||||
// everything happens in the hooks!
|
||||
return tesSUCCESS;
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <ripple/app/tx/applySteps.h>
|
||||
#include <ripple/app/tx/impl/ApplyContext.h>
|
||||
#include <ripple/app/tx/impl/Batch.h>
|
||||
#include <ripple/app/tx/impl/CancelCheck.h>
|
||||
#include <ripple/app/tx/impl/CancelOffer.h>
|
||||
#include <ripple/app/tx/impl/CashCheck.h>
|
||||
@@ -104,6 +105,8 @@ invoke_preflight(PreflightContext const& ctx)
|
||||
return invoke_preflight_helper<DeleteAccount>(ctx);
|
||||
case ttACCOUNT_SET:
|
||||
return invoke_preflight_helper<SetAccount>(ctx);
|
||||
case ttBATCH:
|
||||
return invoke_preflight_helper<Batch>(ctx);
|
||||
case ttCHECK_CANCEL:
|
||||
return invoke_preflight_helper<CancelCheck>(ctx);
|
||||
case ttCHECK_CASH:
|
||||
@@ -223,6 +226,8 @@ invoke_preclaim(PreclaimContext const& ctx)
|
||||
return invoke_preclaim<DeleteAccount>(ctx);
|
||||
case ttACCOUNT_SET:
|
||||
return invoke_preclaim<SetAccount>(ctx);
|
||||
case ttBATCH:
|
||||
return invoke_preclaim<Batch>(ctx);
|
||||
case ttCHECK_CANCEL:
|
||||
return invoke_preclaim<CancelCheck>(ctx);
|
||||
case ttCHECK_CASH:
|
||||
@@ -304,6 +309,8 @@ invoke_calculateBaseFee(ReadView const& view, STTx const& tx)
|
||||
return DeleteAccount::calculateBaseFee(view, tx);
|
||||
case ttACCOUNT_SET:
|
||||
return SetAccount::calculateBaseFee(view, tx);
|
||||
case ttBATCH:
|
||||
return Batch::calculateBaseFee(view, tx);
|
||||
case ttCHECK_CANCEL:
|
||||
return CancelCheck::calculateBaseFee(view, tx);
|
||||
case ttCHECK_CASH:
|
||||
@@ -428,6 +435,10 @@ invoke_apply(ApplyContext& ctx)
|
||||
SetAccount p(ctx);
|
||||
return p();
|
||||
}
|
||||
case ttBATCH: {
|
||||
Batch p(ctx);
|
||||
return p();
|
||||
}
|
||||
case ttCHECK_CANCEL: {
|
||||
CancelCheck p(ctx);
|
||||
return p();
|
||||
|
||||
@@ -604,6 +604,7 @@ extern SField const sfMemos;
|
||||
extern SField const sfNFTokens;
|
||||
extern SField const sfHooks;
|
||||
extern SField const sfGenesisMint;
|
||||
extern SField const sfEmittedTxns;
|
||||
|
||||
// array of objects (uncommon)
|
||||
extern SField const sfMajorities;
|
||||
|
||||
@@ -181,6 +181,8 @@ enum TxType : std::uint16_t
|
||||
ttUNL_MODIFY = 102,
|
||||
ttEMIT_FAILURE = 103,
|
||||
ttUNL_REPORT = 104,
|
||||
|
||||
ttBATCH = 105,
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
|
||||
@@ -366,6 +366,7 @@ CONSTRUCT_UNTYPED_SFIELD(sfDisabledValidators, "DisabledValidators", ARRAY,
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfHookExecutions, "HookExecutions", ARRAY, 18);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfHookParameters, "HookParameters", ARRAY, 19);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfHookGrants, "HookGrants", ARRAY, 20);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfEmittedTxns, "EmittedTxns", ARRAY, 97);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfGenesisMints, "GenesisMints", ARRAY, 96);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfActiveValidators, "ActiveValidators", ARRAY, 95);
|
||||
CONSTRUCT_UNTYPED_SFIELD(sfImportVLKeys, "ImportVLKeys", ARRAY, 94);
|
||||
|
||||
@@ -441,6 +441,13 @@ TxFormats::TxFormats()
|
||||
{sfTicketSequence, soeOPTIONAL},
|
||||
},
|
||||
commonFields);
|
||||
|
||||
add(jss::Batch,
|
||||
ttBATCH,
|
||||
{
|
||||
{sfEmittedTxns, soeOPTIONAL},
|
||||
},
|
||||
commonFields);
|
||||
}
|
||||
|
||||
TxFormats const&
|
||||
|
||||
@@ -50,6 +50,7 @@ JSS(AccountSet); // transaction type.
|
||||
JSS(Amendments); // ledger type.
|
||||
JSS(Amount); // in: TransactionSign; field.
|
||||
JSS(Authorize); // field
|
||||
JSS(Batch); // transaction type.
|
||||
JSS(Blob);
|
||||
JSS(Check); // ledger type.
|
||||
JSS(CheckCancel); // transaction type.
|
||||
|
||||
Reference in New Issue
Block a user