dump bulding

This commit is contained in:
Denis Angell
2024-03-29 18:34:47 +01:00
parent aa438663e8
commit 43fce18099
7 changed files with 162 additions and 100 deletions

View File

@@ -1,12 +1,17 @@
#include <ripple/app/hook/applyHook.h>
#include <ripple/app/ledger/OpenLedger.h>
#include <ripple/app/ledger/TransactionMaster.h>
#include <ripple/app/misc/HashRouter.h>
#include <ripple/app/misc/NetworkOPs.h>
#include <ripple/app/misc/Transaction.h>
#include <ripple/app/misc/TxQ.h>
#include <ripple/app/tx/impl/Import.h>
#include <ripple/app/tx/impl/details/NFTokenUtils.h>
#include <ripple/basics/Log.h>
#include <ripple/basics/Slice.h>
#include <ripple/protocol/ErrorCodes.h>
#include <ripple/protocol/TxFlags.h>
#include <ripple/protocol/st.h>
#include <ripple/protocol/tokens.h>
#include <boost/multiprecision/cpp_dec_float.hpp>
#include <any>

View File

@@ -292,13 +292,13 @@ Batch::preflight(PreflightContext const& ctx)
auto const& txns = tx.getFieldArray(sfRawTransactions);
if (txns.empty())
{
JLOG(ctx.j.warn()) << "Batch: txns array empty.";
JLOG(ctx.j.error()) << "Batch: txns array empty.";
return temMALFORMED;
}
if (txns.size() > 400)
if (txns.size() > 12)
{
JLOG(ctx.j.warn()) << "Batch: txns array exceeds 400 entries.";
JLOG(ctx.j.error()) << "Batch: txns array exceeds 12 entries.";
return temMALFORMED;
}
@@ -306,7 +306,7 @@ Batch::preflight(PreflightContext const& ctx)
{
if (!txn.isFieldPresent(sfTransactionType))
{
JLOG(ctx.j.warn())
JLOG(ctx.j.error())
<< "Batch: TransactionType missing in array entry.";
return temMALFORMED;
}
@@ -343,14 +343,15 @@ Batch::preclaim(PreclaimContext const& ctx)
// Cannot continue on failed txns
if (preflightResponses[i] != tesSUCCESS)
{
JLOG(ctx.j.warn()) << "Batch: Failed Preflight Response: " << preflightResponses[i];
JLOG(ctx.j.error()) << "Batch: Failed Preflight Response: " << preflightResponses[i];
preclaimResponses.push_back(TER(preflightResponses[i]));
continue;
}
auto const& txn = txns[i];
if (!txn.isFieldPresent(sfTransactionType))
{
JLOG(ctx.j.warn())
JLOG(ctx.j.error())
<< "Batch: TransactionType missing in array entry.";
return temMALFORMED;
}
@@ -388,19 +389,22 @@ Batch::doApply()
auto const& txns = ctx_.tx.getFieldArray(sfRawTransactions);
for (std::size_t i = 0; i < txns.size(); ++i)
{
std::cout << "START" << "\n";
ApplyViewImpl& avi = dynamic_cast<ApplyViewImpl&>(ctx_.view());
STObject meta{sfBatchExecution};
auto const& txn = txns[i];
if (!txn.isFieldPresent(sfTransactionType))
{
JLOG(ctx_.journal.warn())
JLOG(ctx_.journal.error())
<< "Batch: TransactionType missing in array entry.";
return temMALFORMED;
}
auto const tt = txn.getFieldU16(sfTransactionType);
auto const txtype = safe_cast<TxType>(tt);
auto const stx =
STTx(txtype, [&txn](STObject& obj) { obj = std::move(txn); });
auto const stx = STTx(txtype, [&txn](STObject& obj) { obj = std::move(txn); });
// OpenView(&ctx_.view())
ApplyContext actx(
ctx_.app,
@@ -410,32 +414,34 @@ Batch::doApply()
ctx_.view().fees().base,
view().flags(),
ctx_.journal);
auto const result = invoke_apply(actx);
// if (result.first == tesSUCCESS)
// {
// ctx_.base_.apply(tesSUCCESS);
// }
// else
// {
// actx.discard();
// }
ApplyViewImpl& avi = dynamic_cast<ApplyViewImpl&>(ctx_.view());
STObject meta{sfBatchExecution};
meta.setFieldU8(sfTransactionResult, TERtoInt(result.first));
meta.setFieldU16(sfTransactionType, tt);
meta.setFieldH256(sfTransactionHash, stx.getTransactionID());
if (result.first == tesSUCCESS)
meta.setFieldH256(sfTransactionHash, stx.getTransactionID());
avi.addBatchExecutionMetaData(std::move(meta));
if (result.first != tesSUCCESS)
{
actx.discard();
}
}
auto const sle = ctx_.base_.read(keylet::account(account_));
if (!sle)
return tefINTERNAL;
std::cout << "ACCOUNT SEQ: " << sle->getFieldU32(sfSequence) << "\n";
auto const sleSrcAcc = sb.peek(keylet::account(account_));
if (!sleSrcAcc)
return tefINTERNAL;
std::cout << "ACCOUNT SEQ: " << sleSrcAcc->getFieldU32(sfSequence) << "\n";
std::cout << "ACCOUNT BALANCE: " << mSourceBalance << "\n";
std::cout << "ACCOUNT BALANCE=: " << sle->getFieldAmount(sfBalance) << "\n";
sleSrcAcc->setFieldAmount(sfBalance, sle->getFieldAmount(sfBalance));
sb.update(sleSrcAcc);
sb.apply(ctx_.rawView());
return tesSUCCESS;
}

View File

@@ -259,9 +259,9 @@ XRPNotCreated::finalize(
// std::cout << "fee.drops: " << feeAdded << "\n";
// std::cout << "dropsAdded: " << dropsAdded.drops() << "\n";
// std::cout << "drops: " << drops << "\n";
// std::cout << "drops=: " << drops_ << "\n";
std::cout << "drops=: " << drops_ << "\n";
// // catch any overflow or funny business
// catch any overflow or funny business
// if (drops > dropsAdded.drops())
// return false;

View File

@@ -30,7 +30,7 @@ mulDiv(std::uint64_t value, std::uint64_t mul, std::uint64_t div)
{
using namespace boost::multiprecision;
uint128_t result;
boost::multiprecision::uint128_t result;
result = multiply(result, value, mul);
result /= div;

View File

@@ -66,7 +66,7 @@ InnerObjectFormats::InnerObjectFormats()
sfBatchExecution.getCode(),
{{sfTransactionType, soeREQUIRED},
{sfTransactionResult, soeREQUIRED},
{sfTransactionHash, soeREQUIRED}});
{sfTransactionHash, soeOPTIONAL}});
add(sfHookExecution.jsonName.c_str(),
sfHookExecution.getCode(),

View File

@@ -44,6 +44,7 @@ TxFormats::TxFormats()
{sfNetworkID, soeOPTIONAL},
{sfHookParameters, soeOPTIONAL},
{sfOperationLimit, soeOPTIONAL},
{sfCloseResolution, soeOPTIONAL},
};
add(jss::AccountSet,

View File

@@ -48,17 +48,42 @@ class Batch_test : public beast::unit_test::suite
++index;
}
}
void
testBatch(FeatureBitset features)
Json::Value
addBatchTx(
Json::Value jv,
Json::Value const& tx,
jtx::Account const& account,
XRPAmount feeDrops,
std::uint32_t index,
std::uint32_t next)
{
testcase("batch");
jv[sfRawTransactions.jsonName][index] = Json::Value{};
jv[sfRawTransactions.jsonName][index][jss::RawTransaction] = tx;
jv[sfRawTransactions.jsonName][index][jss::RawTransaction][jss::SigningPubKey] = strHex(account.pk());
jv[sfRawTransactions.jsonName][index][jss::RawTransaction][sfFee.jsonName] = 0;
jv[sfRawTransactions.jsonName][index][jss::RawTransaction][jss::Sequence] = 0;
jv[sfRawTransactions.jsonName][index][jss::RawTransaction][sfOperationLimit.jsonName] = index;
jv[sfRawTransactions.jsonName][index][jss::RawTransaction][sfCloseResolution.jsonName] = next;
return jv;
}
// OnSucess -> (0)
// OnFailure -> Next Tx Index
// Ex.
// 0: MintURIToken: If Fail -> 2
// 1: Payment: If Fail -> 2
// 2: Payment: 0
void
testBadPubKey(FeatureBitset features)
{
testcase("bad pubkey");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, envconfig()};
auto const feeDrops = env.current()->fees().base;
// Env env{
// *this,
// envconfig(),
@@ -67,14 +92,15 @@ class Batch_test : public beast::unit_test::suite
// // beast::severities::kWarning
// beast::severities::kTrace};
auto const feeDrops = env.current()->fees().base;
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const carol = Account("carol");
env.fund(XRP(1000), alice, bob, carol);
env.fund(XRP(1000), alice, bob);
env.close();
auto const seq = env.seq("alice");
// ttBATCH
Json::Value jv;
jv[jss::TransactionType] = jss::Batch;
@@ -82,39 +108,90 @@ class Batch_test : public beast::unit_test::suite
// Batch Transactions
jv[sfRawTransactions.jsonName] = Json::Value{Json::arrayValue};
// Tx 1
jv[sfRawTransactions.jsonName][0U] = Json::Value{};
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction] = Json::Value{};
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[jss::TransactionType] = jss::AccountSet;
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[sfAccount.jsonName] = alice.human();
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction][sfFee.jsonName] =
to_string(feeDrops);
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction][jss::Sequence] =
seq + 1;
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[jss::SigningPubKey] = strHex(alice.pk());
// Tx 2
jv[sfRawTransactions.jsonName][1U] = Json::Value{};
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction] = Json::Value{};
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[jss::TransactionType] = jss::AccountSet;
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[sfAccount.jsonName] = alice.human();
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction][sfFee.jsonName] =
to_string(feeDrops);
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction][jss::Sequence] =
seq + 2;
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[jss::SigningPubKey] = strHex(alice.pk());
env(jv, fee(drops((2 * feeDrops) + (2 * feeDrops))), ter(tesSUCCESS));
// Tx 1
Json::Value const tx1 = pay(alice, bob, XRP(1));
jv = addBatchTx(jv, tx1, alice, feeDrops, 0, 0);
// Tx 2
Json::Value const tx2 = pay(alice, bob, XRP(1));
jv = addBatchTx(jv, tx2, bob, feeDrops, 1, 0);
env(jv, fee(feeDrops * 2), ter(tesSUCCESS));
env.close();
std::array<TestBatchData, 2> testCases = {{
{"tesSUCCESS", "Payment"},
{"tesSUCCESS", "Payment"},
}};
Json::Value params;
params[jss::transaction] = env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
std::cout << "jrr: " << jrr << "\n";
auto const meta = jrr[jss::result][jss::meta];
validateBatchTxns(meta, testCases);
BEAST_EXPECT(env.seq(alice) == 2);
BEAST_EXPECT(env.balance(alice) == XRP(1000) - XRP(1) - (feeDrops * 2));
BEAST_EXPECT(env.balance(bob) == XRP(1000) + XRP(1));
}
void
testUnfunded(FeatureBitset features)
{
testcase("unfunded");
using namespace test::jtx;
using namespace std::literals;
test::jtx::Env env{*this, envconfig()};
auto const feeDrops = env.current()->fees().base;
auto const alice = Account("alice");
auto const bob = Account("bob");
auto const carol = Account("carol");
env.fund(XRP(1000), alice, bob, carol);
env.close();
auto const seq = env.seq("alice");
// ttBATCH
Json::Value jv;
jv[jss::TransactionType] = jss::Batch;
jv[jss::Account] = alice.human();
// Batch Transactions
jv[sfRawTransactions.jsonName] = Json::Value{Json::arrayValue};
// Tx 1
Json::Value const tx1 = pay(alice, bob, XRP(1));
jv = addBatchTx(jv, tx1, alice, feeDrops, 0, 0);
// Tx 2
Json::Value const tx2 = pay(alice, bob, XRP(999));
jv = addBatchTx(jv, tx2, alice, feeDrops, 1, 0);
env(jv, fee(feeDrops * 2), ter(tesSUCCESS));
env.close();
std::array<TestBatchData, 2> testCases = {{
{"tesSUCCESS", "Payment"},
{"tecUNFUNDED_PAYMENT", "Payment"},
}};
Json::Value params;
params[jss::transaction] = env.tx()->getJson(JsonOptions::none)[jss::hash];
auto const jrr = env.rpc("json", "tx", to_string(params));
std::cout << "jrr: " << jrr << "\n";
auto const meta = jrr[jss::result][jss::meta];
validateBatchTxns(meta, testCases);
BEAST_EXPECT(env.seq(alice) == 2);
BEAST_EXPECT(env.balance(alice) == XRP(1000) - XRP(1) - (feeDrops * 1));
BEAST_EXPECT(env.balance(bob) == XRP(1000) + XRP(1));
}
void
testSuccess(FeatureBitset features)
{
@@ -150,40 +227,12 @@ class Batch_test : public beast::unit_test::suite
jv[sfRawTransactions.jsonName] = Json::Value{Json::arrayValue};
// Tx 1
jv[sfRawTransactions.jsonName][0U] = Json::Value{};
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction] = Json::Value{};
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[jss::TransactionType] = jss::Payment;
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[sfAccount.jsonName] = alice.human();
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[sfDestination.jsonName] = bob.human();
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[sfAmount.jsonName] = "1000000";
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction][sfFee.jsonName] =
to_string(feeDrops);
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction][jss::Sequence] =
seq + 1;
jv[sfRawTransactions.jsonName][0U][jss::RawTransaction]
[jss::SigningPubKey] = strHex(alice.pk());
Json::Value const tx1 = pay(alice, bob, XRP(1));
jv = addBatchTx(jv, tx1, alice, feeDrops, 0, 0);
// Tx 2
jv[sfRawTransactions.jsonName][1U] = Json::Value{};
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction] = Json::Value{};
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[jss::TransactionType] = jss::Payment;
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[sfAccount.jsonName] = alice.human();
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[sfDestination.jsonName] = bob.human();
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[sfAmount.jsonName] = "1000000";
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction][sfFee.jsonName] =
to_string(feeDrops);
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction][jss::Sequence] =
seq + 2;
jv[sfRawTransactions.jsonName][1U][jss::RawTransaction]
[jss::SigningPubKey] = strHex(alice.pk());
Json::Value const tx2 = pay(alice, bob, XRP(1));
jv = addBatchTx(jv, tx2, alice, feeDrops, 1, 0);
env(jv, fee(feeDrops * 2), ter(tesSUCCESS));
env.close();
@@ -200,7 +249,7 @@ class Batch_test : public beast::unit_test::suite
auto const meta = jrr[jss::result][jss::meta];
validateBatchTxns(meta, testCases);
BEAST_EXPECT(env.seq(alice) == 4);
BEAST_EXPECT(env.seq(alice) == 2);
BEAST_EXPECT(env.balance(alice) == XRP(1000) - XRP(2) - (feeDrops * 2));
BEAST_EXPECT(env.balance(bob) == XRP(1000) + XRP(2));
}
@@ -325,8 +374,9 @@ class Batch_test : public beast::unit_test::suite
void
testWithFeats(FeatureBitset features)
{
// testBatch(features);
testSuccess(features);
// testBadPubKey(features);
testUnfunded(features);
// testSuccess(features);
// testSingle(features);
// testInvalidBatch(features);
}