xrpld
Loading...
Searching...
No Matches
tests/libxrpl/tx/ProposalHelpers.cpp
1#include <xrpl/ledger/helpers/ProposalHelpers.h>
2
3#include <xrpl/protocol/SField.h>
4#include <xrpl/protocol/STArray.h>
5#include <xrpl/protocol/STObject.h>
6#include <xrpl/protocol/TxFlags.h>
7#include <xrpl/protocol/TxFormats.h>
8
9#include <gtest/gtest.h>
10
11#include <cstdint>
12#include <utility>
13
14namespace xrpl::test {
15
16namespace {
17
18// A bare STObject carrying only sfTransactionType. isValidProposal accepts an
19// STObject (not an STTx) precisely so that this file's defense-in-depth
20// checks can be tested without the surrounding STTx format validation.
21inline STObject
22txOfType(std::uint16_t txType)
23{
24 STObject tx(sfGeneric);
25 tx.setFieldU16(sfTransactionType, txType);
26 return tx;
27}
28
29// A bare Batch STObject wrapping the given inner transaction as its single
30// sfRawTransactions entry.
31inline STObject
32batchWrapping(STObject inner)
33{
34 STArray rawTxns(sfRawTransactions);
35 rawTxns.push_back(std::move(inner));
36
37 STObject batch(sfGeneric);
38 batch.setFieldU16(sfTransactionType, ttBATCH);
39 batch.setFieldArray(sfRawTransactions, rawTxns);
40 return batch;
41}
42
43} // namespace
44
45// The happy path — an ordinary Payment is independently submittable.
46TEST(ProposalHelpers, plain_payment_is_valid)
47{
48 EXPECT_TRUE(proposal::isValidProposal(txOfType(ttPAYMENT)));
49}
50
51// A nested TransactionProposalCreate. In practice STTx construction rejects
52// this earlier (the payload lacks TransactionProposalCreate's own template
53// fields), but the defense here re-checks that guard so the two cannot
54// drift apart.
55TEST(ProposalHelpers, nested_proposal_is_rejected)
56{
57 EXPECT_FALSE(proposal::isValidProposal(txOfType(ttTRANSACTION_PROPOSAL_CREATE)));
58}
59
60// Any pseudo-transaction — see STTx::isPseudoTx. Also normally caught earlier
61// by STTx construction / preflight0.
62TEST(ProposalHelpers, pseudo_tx_is_rejected)
63{
64 EXPECT_FALSE(proposal::isValidProposal(txOfType(ttAMENDMENT)));
65 EXPECT_FALSE(proposal::isValidProposal(txOfType(ttFEE)));
66 EXPECT_FALSE(proposal::isValidProposal(txOfType(ttUNL_MODIFY)));
67}
68
69// tfInnerBatchTxn marks a transaction as an inner leg of an enclosing Batch,
70// so it must never stand on its own as a proposed transaction. preflight0
71// rejects the standalone case with temINVALID_INNER_BATCH before we get
72// here; the guard is re-checked so the two cannot drift apart.
73TEST(ProposalHelpers, inner_batch_flag_is_rejected)
74{
75 STObject tx = txOfType(ttPAYMENT);
76 tx.setFieldU32(sfFlags, tfInnerBatchTxn);
77 EXPECT_FALSE(proposal::isValidProposal(tx));
78}
79
80// A Flags value that is present but does not include tfInnerBatchTxn must
81// not be rejected — the check is bit-specific, not "any flag present".
82TEST(ProposalHelpers, other_flags_are_accepted)
83{
84 STObject tx = txOfType(ttPAYMENT);
86 EXPECT_TRUE(proposal::isValidProposal(tx));
87}
88
89// A Batch wrapping a plain inner is fine — the loop is only there to catch
90// specifically forbidden inner types.
91TEST(ProposalHelpers, batch_with_plain_inner_is_valid)
92{
93 EXPECT_TRUE(proposal::isValidProposal(batchWrapping(txOfType(ttPAYMENT))));
94}
95
96// A Batch whose inner is itself a proposal must be rejected.
97TEST(ProposalHelpers, batch_with_nested_proposal_inner_is_rejected)
98{
99 EXPECT_FALSE(proposal::isValidProposal(batchWrapping(txOfType(ttTRANSACTION_PROPOSAL_CREATE))));
100}
101
102// A Batch whose inner is a pseudo-transaction must be rejected.
103TEST(ProposalHelpers, batch_with_pseudo_inner_is_rejected)
104{
105 EXPECT_FALSE(proposal::isValidProposal(batchWrapping(txOfType(ttAMENDMENT))));
106}
107
108// A Batch with no sfRawTransactions field skips the inner-loop entirely.
109// Not something the transactor would ever emit, but the branch exists in the
110// helper (the field is optional at the STObject level) and should hold.
111TEST(ProposalHelpers, batch_without_raw_transactions_is_valid)
112{
113 EXPECT_TRUE(proposal::isValidProposal(txOfType(ttBATCH)));
114}
115
116} // namespace xrpl::test
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:743
bool isValidProposal(STObject const &proposedTx)
Whether the proposed transaction is independently submittable through the ordinary multi-sign path: n...
Helpers for constructing Batch test transactions.
Definition batch.h:26
TEST(UnitsTest, types)
Definition Units.cpp:16
constexpr FlagValue tfInnerBatchTxn
Definition TxFlags.h:44
SField const sfGeneric
constexpr FlagValue tfFullyCanonicalSig
Definition TxFlags.h:43