rippled
Loading...
Searching...
No Matches
STTx.cpp
1#include <xrpl/basics/Blob.h>
2#include <xrpl/basics/Expected.h>
3#include <xrpl/basics/Log.h>
4#include <xrpl/basics/Slice.h>
5#include <xrpl/basics/StringUtilities.h>
6#include <xrpl/basics/base_uint.h>
7#include <xrpl/basics/contract.h>
8#include <xrpl/basics/safe_cast.h>
9#include <xrpl/basics/strHex.h>
10#include <xrpl/beast/utility/Zero.h>
11#include <xrpl/beast/utility/instrumentation.h>
12#include <xrpl/json/json_value.h>
13#include <xrpl/protocol/AccountID.h>
14#include <xrpl/protocol/Batch.h>
15#include <xrpl/protocol/HashPrefix.h>
16#include <xrpl/protocol/MPTIssue.h>
17#include <xrpl/protocol/Protocol.h>
18#include <xrpl/protocol/PublicKey.h>
19#include <xrpl/protocol/Rules.h>
20#include <xrpl/protocol/SField.h>
21#include <xrpl/protocol/SOTemplate.h>
22#include <xrpl/protocol/STAccount.h>
23#include <xrpl/protocol/STAmount.h>
24#include <xrpl/protocol/STArray.h>
25#include <xrpl/protocol/STBase.h>
26#include <xrpl/protocol/STObject.h>
27#include <xrpl/protocol/STTx.h>
28#include <xrpl/protocol/STVector256.h>
29#include <xrpl/protocol/SecretKey.h>
30#include <xrpl/protocol/SeqProxy.h>
31#include <xrpl/protocol/Serializer.h>
32#include <xrpl/protocol/Sign.h>
33#include <xrpl/protocol/TxFlags.h>
34#include <xrpl/protocol/TxFormats.h>
35#include <xrpl/protocol/jss.h>
36
37#include <boost/container/flat_set.hpp>
38#include <boost/format/format_fwd.hpp>
39#include <boost/format/free_funcs.hpp>
40
41#include <array>
42#include <cstddef>
43#include <cstdint>
44#include <exception>
45#include <functional>
46#include <memory>
47#include <optional>
48#include <stdexcept>
49#include <string>
50#include <string_view>
51#include <type_traits>
52#include <utility>
53
54namespace xrpl {
55
56static auto
58{
59 auto format = TxFormats::getInstance().findByType(type);
60
61 if (format == nullptr)
62 {
63 Throw<std::runtime_error>(
64 "Invalid transaction type " +
66 }
67
68 return format;
69}
70
71STTx::STTx(STObject&& object) : STObject(std::move(object))
72{
73 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
74 applyTemplate(getTxFormat(tx_type_)->getSOTemplate()); // may throw
76}
77
78STTx::STTx(SerialIter& sit) : STObject(sfTransaction)
79{
80 int length = sit.getBytesLeft();
81
82 if ((length < txMinSizeBytes) || (length > txMaxSizeBytes))
83 Throw<std::runtime_error>("Transaction length invalid");
84
85 if (set(sit))
86 Throw<std::runtime_error>("Transaction contains an object terminator");
87
88 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
89
90 applyTemplate(getTxFormat(tx_type_)->getSOTemplate()); // May throw
92}
93
94STTx::STTx(TxType type, std::function<void(STObject&)> assembler) : STObject(sfTransaction)
95{
96 auto format = getTxFormat(type);
97
98 set(format->getSOTemplate());
99 setFieldU16(sfTransactionType, format->getType());
100
101 assembler(*this);
102
103 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
104
105 if (tx_type_ != type)
106 LogicError("Transaction type was mutated during assembly");
107
109}
110
111STBase*
112STTx::copy(std::size_t n, void* buf) const
113{
114 return emplace(n, buf, *this);
115}
116
117STBase*
119{
120 return emplace(n, buf, std::move(*this));
121}
122
123// STObject functions.
126{
127 return STI_TRANSACTION;
128}
129
132{
133 std::string ret = "\"";
134 ret += to_string(getTransactionID());
135 ret += "\" = {";
136 ret += STObject::getFullText();
137 ret += "}";
138 return ret;
139}
140
141boost::container::flat_set<AccountID>
143{
144 boost::container::flat_set<AccountID> list;
145
146 for (auto const& it : *this)
147 {
148 if (auto sacc = dynamic_cast<STAccount const*>(&it))
149 {
150 XRPL_ASSERT(!sacc->isDefault(), "xrpl::STTx::getMentionedAccounts : account is set");
151 if (!sacc->isDefault())
152 list.insert(sacc->value());
153 }
154 else if (auto samt = dynamic_cast<STAmount const*>(&it))
155 {
156 auto const& issuer = samt->getIssuer();
157 if (!isXRP(issuer))
158 list.insert(issuer);
159 }
160 }
161
162 return list;
163}
164
165static Blob
167{
168 Serializer s;
171 return s.getData();
172}
173
179
180Blob
182{
183 try
184 {
185 return sigObject.getFieldVL(sfTxnSignature);
186 }
187 catch (std::exception const&)
188 {
189 return Blob();
190 }
191}
192
195{
196 std::uint32_t const seq{getFieldU32(sfSequence)};
197 if (seq != 0)
198 return SeqProxy::sequence(seq);
199
200 std::optional<std::uint32_t> const ticketSeq{operator[](~sfTicketSequence)};
201 if (!ticketSeq)
202 // No TicketSequence specified. Return the Sequence, whatever it is.
203 return SeqProxy::sequence(seq);
204
205 return SeqProxy{SeqProxy::ticket, *ticketSeq};
206}
207
210{
211 return getSeqProxy().value();
212}
213
214void
216 PublicKey const& publicKey,
217 SecretKey const& secretKey,
219{
220 auto const data = getSigningData(*this);
221
222 auto const sig = xrpl::sign(publicKey, secretKey, makeSlice(data));
223
224 if (signatureTarget)
225 {
226 auto& target = peekFieldObject(*signatureTarget);
227 target.setFieldVL(sfTxnSignature, sig);
228 }
229 else
230 {
231 setFieldVL(sfTxnSignature, sig);
232 }
234}
235
237STTx::checkSign(Rules const& rules, STObject const& sigObject) const
238{
239 try
240 {
241 // Determine whether we're single- or multi-signing by looking
242 // at the SigningPubKey. If it's empty we must be
243 // multi-signing. Otherwise we're single-signing.
244
245 Blob const& signingPubKey = sigObject.getFieldVL(sfSigningPubKey);
246 return signingPubKey.empty() ? checkMultiSign(rules, sigObject)
247 : checkSingleSign(sigObject);
248 }
249 catch (std::exception const&)
250 {
251 }
252 return Unexpected("Internal signature check failure.");
253}
254
256STTx::checkSign(Rules const& rules) const
257{
258 if (auto const ret = checkSign(rules, *this); !ret)
259 return ret;
260
261 if (isFieldPresent(sfCounterpartySignature))
262 {
263 auto const counterSig = getFieldObject(sfCounterpartySignature);
264 if (auto const ret = checkSign(rules, counterSig); !ret)
265 return Unexpected("Counterparty: " + ret.error());
266 }
267 return {};
268}
269
271STTx::checkBatchSign(Rules const& rules) const
272{
273 try
274 {
275 XRPL_ASSERT(getTxnType() == ttBATCH, "STTx::checkBatchSign : not a batch transaction");
276 if (getTxnType() != ttBATCH)
277 {
278 JLOG(debugLog().fatal()) << "not a batch transaction";
279 return Unexpected("Not a batch transaction.");
280 }
281 STArray const& signers{getFieldArray(sfBatchSigners)};
282 for (auto const& signer : signers)
283 {
284 Blob const& signingPubKey = signer.getFieldVL(sfSigningPubKey);
285 auto const result = signingPubKey.empty() ? checkBatchMultiSign(signer, rules)
286 : checkBatchSingleSign(signer);
287
288 if (!result)
289 return result;
290 }
291 return {};
292 }
293 catch (std::exception const& e)
294 {
295 JLOG(debugLog().error()) << "Batch signature check failed: " << e.what();
296 }
297 return Unexpected("Internal batch signature check failure.");
298}
299
302{
304 if (!(options & JsonOptions::disable_API_prior_V2))
305 ret[jss::hash] = to_string(getTransactionID());
306 return ret;
307}
308
310STTx::getJson(JsonOptions options, bool binary) const
311{
312 bool const V1 = !(options & JsonOptions::disable_API_prior_V2);
313
314 if (binary)
315 {
317 std::string const dataBin = strHex(s.peekData());
318
319 if (V1)
320 {
322 ret[jss::tx] = dataBin;
323 ret[jss::hash] = to_string(getTransactionID());
324 return ret;
325 }
326 else
327 return Json::Value{dataBin};
328 }
329
331 if (V1)
332 ret[jss::hash] = to_string(getTransactionID());
333
334 return ret;
335}
336
337std::string const&
339{
340 static std::string const sql =
341 "INSERT OR REPLACE INTO Transactions "
342 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, "
343 "TxnMeta)"
344 " VALUES ";
345
346 return sql;
347}
348
350STTx::getMetaSQL(std::uint32_t inLedger, std::string const& escapedMetaData) const
351{
352 Serializer s;
353 add(s);
354 return getMetaSQL(s, inLedger, txnSqlValidated, escapedMetaData);
355}
356
357// VFALCO This could be a free function elsewhere
360 Serializer rawTxn,
361 std::uint32_t inLedger,
362 char status,
363 std::string const& escapedMetaData) const
364{
365 static boost::format bfTrans("('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
366 std::string rTxn = sqlBlobLiteral(rawTxn.peekData());
367
369 XRPL_ASSERT(format, "xrpl::STTx::getMetaSQL : non-null type format");
370
371 return str(
372 boost::format(bfTrans) % to_string(getTransactionID()) % format->getName() %
373 toBase58(getAccountID(sfAccount)) % getFieldU32(sfSequence) % inLedger % status % rTxn %
374 escapedMetaData);
375}
376
378singleSignHelper(STObject const& sigObject, Slice const& data)
379{
380 // We don't allow both a non-empty sfSigningPubKey and an sfSigners.
381 // That would allow the transaction to be signed two ways. So if both
382 // fields are present the signature is invalid.
383 if (sigObject.isFieldPresent(sfSigners))
384 return Unexpected("Cannot both single- and multi-sign.");
385
386 bool validSig = false;
387 try
388 {
389 auto const spk = sigObject.getFieldVL(sfSigningPubKey);
390 if (publicKeyType(makeSlice(spk)))
391 {
392 Blob const signature = sigObject.getFieldVL(sfTxnSignature);
393 validSig = verify(PublicKey(makeSlice(spk)), data, makeSlice(signature));
394 }
395 }
396 catch (std::exception const&)
397 {
398 validSig = false;
399 }
400
401 if (!validSig)
402 return Unexpected("Invalid signature.");
403
404 return {};
405}
406
407Expected<void, std::string>
408STTx::checkSingleSign(STObject const& sigObject) const
409{
410 auto const data = getSigningData(*this);
411 return singleSignHelper(sigObject, makeSlice(data));
412}
413
415STTx::checkBatchSingleSign(STObject const& batchSigner) const
416{
417 Serializer msg;
419 return singleSignHelper(batchSigner, msg.slice());
420}
421
424 STObject const& sigObject,
425 std::optional<AccountID> txnAccountID,
426 std::function<Serializer(AccountID const&)> makeMsg,
427 Rules const& rules)
428{
429 // Make sure the MultiSigners are present. Otherwise they are not
430 // attempting multi-signing and we just have a bad SigningPubKey.
431 if (!sigObject.isFieldPresent(sfSigners))
432 return Unexpected("Empty SigningPubKey.");
433
434 // We don't allow both an sfSigners and an sfTxnSignature. Both fields
435 // being present would indicate that the transaction is signed both ways.
436 if (sigObject.isFieldPresent(sfTxnSignature))
437 return Unexpected("Cannot both single- and multi-sign.");
438
439 STArray const& signers{sigObject.getFieldArray(sfSigners)};
440
441 // There are well known bounds that the number of signers must be within.
442 if (signers.size() < STTx::minMultiSigners || signers.size() > STTx::maxMultiSigners)
443 return Unexpected("Invalid Signers array size.");
444
445 // Signers must be in sorted order by AccountID.
446 AccountID lastAccountID(beast::zero);
447
448 for (auto const& signer : signers)
449 {
450 auto const accountID = signer.getAccountID(sfAccount);
451
452 // The account owner may not usually multisign for themselves.
453 // If they can, txnAccountID will be unseated, which is not equal to any
454 // value.
455 if (txnAccountID == accountID)
456 return Unexpected("Invalid multisigner.");
457
458 // No duplicate signers allowed.
459 if (lastAccountID == accountID)
460 return Unexpected("Duplicate Signers not allowed.");
461
462 // Accounts must be in order by account ID. No duplicates allowed.
463 if (lastAccountID > accountID)
464 return Unexpected("Unsorted Signers array.");
465
466 // The next signature must be greater than this one.
467 lastAccountID = accountID;
468
469 // Verify the signature.
470 bool validSig = false;
472 try
473 {
474 auto spk = signer.getFieldVL(sfSigningPubKey);
475 if (publicKeyType(makeSlice(spk)))
476 {
477 Blob const signature = signer.getFieldVL(sfTxnSignature);
478 validSig = verify(
479 PublicKey(makeSlice(spk)), makeMsg(accountID).slice(), makeSlice(signature));
480 }
481 }
482 catch (std::exception const& e)
483 {
484 // We assume any problem lies with the signature.
485 validSig = false;
486 errorWhat = e.what();
487 }
488 if (!validSig)
489 return Unexpected(
490 std::string("Invalid signature on account ") + toBase58(accountID) +
491 errorWhat.value_or("") + ".");
492 }
493 // All signatures verified.
494 return {};
495}
496
497Expected<void, std::string>
498STTx::checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const
499{
500 // We can ease the computational load inside the loop a bit by
501 // pre-constructing part of the data that we hash. Fill a Serializer
502 // with the stuff that stays constant from signature to signature.
503 Serializer dataStart;
505 return multiSignHelper(
506 batchSigner,
508 [&dataStart](AccountID const& accountID) -> Serializer {
509 Serializer s = dataStart;
510 finishMultiSigningData(accountID, s);
511 return s;
512 },
513 rules);
514}
515
517STTx::checkMultiSign(Rules const& rules, STObject const& sigObject) const
518{
519 // Used inside the loop in multiSignHelper to enforce that
520 // the account owner may not multisign for themselves.
521 auto const txnAccountID =
522 &sigObject != this ? std::nullopt : std::optional<AccountID>(getAccountID(sfAccount));
523
524 // We can ease the computational load inside the loop a bit by
525 // pre-constructing part of the data that we hash. Fill a Serializer
526 // with the stuff that stays constant from signature to signature.
527 Serializer dataStart = startMultiSigningData(*this);
528 return multiSignHelper(
529 sigObject,
530 txnAccountID,
531 [&dataStart](AccountID const& accountID) -> Serializer {
532 Serializer s = dataStart;
533 finishMultiSigningData(accountID, s);
534 return s;
535 },
536 rules);
537}
538
556{
557 XRPL_ASSERT(getTxnType() == ttBATCH, "STTx::getBatchTransactionIDs : not a batch transaction");
558 XRPL_ASSERT(
559 getFieldArray(sfRawTransactions).size() != 0,
560 "STTx::getBatchTransactionIDs : empty raw transactions");
561
562 // The list of inner ids is built once, then reused on subsequent calls.
563 // After the list is built, it must always have the same size as the array
564 // `sfRawTransactions`. The assert below verifies that.
565 if (batchTxnIds_.size() == 0)
566 {
567 for (STObject const& rb : getFieldArray(sfRawTransactions))
568 batchTxnIds_.push_back(rb.getHash(HashPrefix::transactionID));
569 }
570
571 XRPL_ASSERT(
572 batchTxnIds_.size() == getFieldArray(sfRawTransactions).size(),
573 "STTx::getBatchTransactionIDs : batch transaction IDs size mismatch");
574 return batchTxnIds_;
575}
576
577//------------------------------------------------------------------------------
578
579static bool
580isMemoOkay(STObject const& st, std::string& reason)
581{
582 if (!st.isFieldPresent(sfMemos))
583 return true;
584
585 auto const& memos = st.getFieldArray(sfMemos);
586
587 // The number 2048 is a preallocation hint, not a hard limit
588 // to avoid allocate/copy/free's
589 Serializer s(2048);
590 memos.add(s);
591
592 // FIXME move the memo limit into a config tunable
593 if (s.getDataLength() > 1024)
594 {
595 reason = "The memo exceeds the maximum allowed size.";
596 return false;
597 }
598
599 for (auto const& memo : memos)
600 {
601 auto memoObj = dynamic_cast<STObject const*>(&memo);
602
603 if (!memoObj || (memoObj->getFName() != sfMemo))
604 {
605 reason = "A memo array may contain only Memo objects.";
606 return false;
607 }
608
609 for (auto const& memoElement : *memoObj)
610 {
611 auto const& name = memoElement.getFName();
612
613 if (name != sfMemoType && name != sfMemoData && name != sfMemoFormat)
614 {
615 reason =
616 "A memo may contain only MemoType, MemoData or "
617 "MemoFormat fields.";
618 return false;
619 }
620
621 // The raw data is stored as hex-octets, which we want to decode.
622 auto optData = strUnHex(memoElement.getText());
623
624 if (!optData)
625 {
626 reason =
627 "The MemoType, MemoData and MemoFormat fields may "
628 "only contain hex-encoded data.";
629 return false;
630 }
631
632 if (name == sfMemoData)
633 continue;
634
635 // The only allowed characters for MemoType and MemoFormat are the
636 // characters allowed in URLs per RFC 3986: alphanumerics and the
637 // following symbols: -._~:/?#[]@!$&'()*+,;=%
638 static constexpr std::array<char, 256> const allowedSymbols = []() {
640
641 std::string_view symbols(
642 "0123456789"
643 "-._~:/?#[]@!$&'()*+,;=%"
644 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
645 "abcdefghijklmnopqrstuvwxyz");
646
647 for (unsigned char c : symbols)
648 a[c] = 1;
649 return a;
650 }();
651
652 for (unsigned char c : *optData)
653 {
654 if (!allowedSymbols[c])
655 {
656 reason =
657 "The MemoType and MemoFormat fields may only "
658 "contain characters that are allowed in URLs "
659 "under RFC 3986.";
660 return false;
661 }
662 }
663 }
664 }
665
666 return true;
667}
668
669// Ensure all account fields are 160-bits
670static bool
672{
673 for (int i = 0; i < st.getCount(); ++i)
674 {
675 auto t = dynamic_cast<STAccount const*>(st.peekAtPIndex(i));
676 if (t && t->isDefault())
677 return false;
678 }
679
680 return true;
681}
682
683static bool
685{
686 auto const txType = tx[~sfTransactionType];
687 if (!txType)
688 return false;
689 if (auto const* item = TxFormats::getInstance().findByType(safe_cast<TxType>(*txType)))
690 {
691 for (auto const& e : item->getSOTemplate())
692 {
693 if (tx.isFieldPresent(e.sField()) && e.supportMPT() != soeMPTNone)
694 {
695 if (auto const& field = tx.peekAtField(e.sField());
696 (field.getSType() == STI_AMOUNT &&
697 static_cast<STAmount const&>(field).holds<MPTIssue>()) ||
698 (field.getSType() == STI_ISSUE &&
699 static_cast<STIssue const&>(field).holds<MPTIssue>()))
700 {
701 if (e.supportMPT() != soeMPTSupported)
702 return true;
703 }
704 }
705 }
706 }
707 return false;
708}
709
710static bool
712{
713 if (!st.isFieldPresent(sfRawTransactions))
714 return true;
715
716 if (st.isFieldPresent(sfBatchSigners) &&
717 st.getFieldArray(sfBatchSigners).size() > maxBatchTxCount)
718 {
719 reason = "Batch Signers array exceeds max entries.";
720 return false;
721 }
722
723 auto const& rawTxns = st.getFieldArray(sfRawTransactions);
724 if (rawTxns.size() > maxBatchTxCount)
725 {
726 reason = "Raw Transactions array exceeds max entries.";
727 return false;
728 }
729 for (STObject raw : rawTxns)
730 {
731 try
732 {
733 TxType const tt = safe_cast<TxType>(raw.getFieldU16(sfTransactionType));
734 if (tt == ttBATCH)
735 {
736 reason = "Raw Transactions may not contain batch transactions.";
737 return false;
738 }
739
740 raw.applyTemplate(getTxFormat(tt)->getSOTemplate());
741 }
742 catch (std::exception const& e)
743 {
744 reason = e.what();
745 return false;
746 }
747 }
748 return true;
749}
750
751bool
753{
754 if (!isMemoOkay(st, reason))
755 return false;
756
757 if (!isAccountFieldOkay(st))
758 {
759 reason = "An account field is invalid.";
760 return false;
761 }
762
763 if (isPseudoTx(st))
764 {
765 reason = "Cannot submit pseudo transactions.";
766 return false;
767 }
768
769 if (invalidMPTAmountInTx(st))
770 {
771 reason = "Amount can not be MPT.";
772 return false;
773 }
774
775 if (!isRawTransactionOkay(st, reason))
776 return false;
777
778 return true;
779}
780
782sterilize(STTx const& stx)
783{
784 Serializer s;
785 stx.add(s);
786 SerialIter sit(s.slice());
788}
789
790bool
792{
793 auto const t = tx[~sfTransactionType];
794
795 if (!t)
796 return false;
797
798 auto const tt = safe_cast<TxType>(*t);
799
800 return tt == ttAMENDMENT || tt == ttFEE || tt == ttUNL_MODIFY;
801}
802
803} // namespace xrpl
Represents a JSON value.
Definition json_value.h:130
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
A public key.
Definition PublicKey.h:42
Rules controlling protocol behavior.
Definition Rules.h:18
size_type size() const
Definition STArray.h:225
A type which can be exported to a well known binary format.
Definition STBase.h:115
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition STBase.h:213
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:1011
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STObject.cpp:822
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:632
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:968
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:584
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:768
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1024
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:151
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:358
std::string getFullText() const override
Definition STObject.cpp:283
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:671
STObject & peekFieldObject(SField const &field)
Definition STObject.cpp:458
void add(Serializer &s) const override
Definition STObject.cpp:120
Serializer getSerializer() const
Definition STObject.h:977
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:447
int getCount() const
Definition STObject.h:993
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:720
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:392
void set(SOTemplate const &)
Definition STObject.cpp:135
uint256 getSigningHash(HashPrefix prefix) const
Definition STObject.cpp:367
STObject getFieldObject(SField const &field) const
Definition STObject.cpp:661
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:626
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:578
std::uint32_t getFlags() const
Definition STObject.cpp:500
std::string getFullText() const override
Definition STTx.cpp:131
Expected< void, std::string > checkBatchSingleSign(STObject const &batchSigner) const
Definition STTx.cpp:415
STBase * move(std::size_t n, void *buf) override
Definition STTx.cpp:118
Blob getSignature() const
Definition STTx.h:65
std::string getMetaSQL(std::uint32_t inLedger, std::string const &escapedMetaData) const
Definition STTx.cpp:350
TxType tx_type_
Definition STTx.h:30
Expected< void, std::string > checkMultiSign(Rules const &rules, STObject const &sigObject) const
Definition STTx.cpp:517
uint256 tid_
Definition STTx.h:29
Expected< void, std::string > checkBatchSign(Rules const &rules) const
Definition STTx.cpp:271
Json::Value getJson(JsonOptions options) const override
Definition STTx.cpp:301
static std::string const & getMetaSQLInsertReplaceHeader()
Definition STTx.cpp:338
std::vector< uint256 > const & getBatchTransactionIDs() const
Retrieves a batch of transaction IDs from the STTx.
Definition STTx.cpp:555
Expected< void, std::string > checkBatchMultiSign(STObject const &batchSigner, Rules const &rules) const
Definition STTx.cpp:498
SeqProxy getSeqProxy() const
Definition STTx.cpp:194
STBase * copy(std::size_t n, void *buf) const override
Definition STTx.cpp:112
STTx()=delete
static constexpr std::size_t minMultiSigners
Definition STTx.h:33
Expected< void, std::string > checkSign(Rules const &rules) const
Check the signature.
Definition STTx.cpp:256
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition STTx.cpp:209
TxType getTxnType() const
Definition STTx.h:184
std::vector< uint256 > batchTxnIds_
Definition STTx.h:159
Expected< void, std::string > checkSingleSign(STObject const &sigObject) const
Definition STTx.cpp:408
uint256 getSigningHash() const
Definition STTx.cpp:175
static constexpr std::size_t maxMultiSigners
Definition STTx.h:34
uint256 getTransactionID() const
Definition STTx.h:196
SerializedTypeID getSType() const override
Definition STTx.cpp:125
boost::container::flat_set< AccountID > getMentionedAccounts() const
Definition STTx.cpp:142
void sign(PublicKey const &publicKey, SecretKey const &secretKey, std::optional< std::reference_wrapper< SField const > > signatureTarget={})
Definition STTx.cpp:215
A secret key.
Definition SecretKey.h:18
A type that represents either a sequence value or a ticket value.
Definition SeqProxy.h:36
static constexpr SeqProxy sequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
Definition SeqProxy.h:56
constexpr std::uint32_t value() const
Definition SeqProxy.h:62
int getBytesLeft() const noexcept
Definition Serializer.h:349
Blob const & peekData() const
Definition Serializer.h:176
Slice slice() const noexcept
Definition Serializer.h:44
Blob getData() const
Definition Serializer.h:181
int getDataLength() const
Definition Serializer.h:192
An immutable linear range of bytes.
Definition Slice.h:26
static TxFormats const & getInstance()
Definition TxFormats.cpp:51
T empty(T... args)
T is_same_v
@ objectValue
object value (collection of name/value pairs).
Definition json_value.h:26
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
std::size_t constexpr txMinSizeBytes
Protocol specific constants.
Definition Protocol.h:22
Serializer startMultiSigningData(STObject const &obj)
Break the multi-signing hash computation into 2 parts for optimization.
Definition Sign.cpp:80
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
TxType
Transaction type identifiers.
Definition TxFormats.h:37
bool isXRP(AccountID const &c)
Definition AccountID.h:70
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:449
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:600
std::string strHex(FwdIt begin, FwdIt end)
Definition strHex.h:10
Expected< void, std::string > multiSignHelper(STObject const &sigObject, std::optional< AccountID > txnAccountID, std::function< Serializer(AccountID const &)> makeMsg, Rules const &rules)
Definition STTx.cpp:423
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:92
static bool isMemoOkay(STObject const &st, std::string &reason)
Definition STTx.cpp:580
static auto getTxFormat(TxType type)
Definition STTx.cpp:57
@ txnSqlValidated
Definition STTx.h:22
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
base_uint< 256 > uint256
Definition base_uint.h:529
static bool isAccountFieldOkay(STObject const &st)
Definition STTx.cpp:671
void finishMultiSigningData(AccountID const &signingID, Serializer &s)
Definition Sign.h:64
std::size_t constexpr txMaxSizeBytes
Largest legal byte size of a transaction.
Definition Protocol.h:25
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
SerializedTypeID
Definition SField.h:90
std::vector< unsigned char > Blob
Storage for linear binary data.
Definition Blob.h:10
bool passesLocalChecks(STObject const &st, std::string &)
Definition STTx.cpp:752
static bool invalidMPTAmountInTx(STObject const &tx)
Definition STTx.cpp:684
std::size_t constexpr maxBatchTxCount
The maximum number of transactions that can be in a batch.
Definition Protocol.h:308
static bool isRawTransactionOkay(STObject const &st, std::string &reason)
Definition STTx.cpp:711
static Expected< void, std::string > singleSignHelper(STObject const &sigObject, Slice const &data)
Definition STTx.cpp:378
@ txSign
inner transaction to sign
@ transactionID
transaction plus signature to give transaction ID
std::string sqlBlobLiteral(Blob const &blob)
Format arbitrary binary data as an SQLite "blob literal".
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
static Blob getSigningData(STTx const &that)
Definition STTx.cpp:166
void serializeBatch(Serializer &msg, std::uint32_t const &flags, std::vector< uint256 > const &txids)
std::enable_if_t< std::is_same< T, char >::value||std::is_same< T, unsigned char >::value, Slice > makeSlice(std::array< T, N > const &a)
Definition Slice.h:215
@ soeMPTSupported
Definition SOTemplate.h:23
@ soeMPTNone
Definition SOTemplate.h:23
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition STTx.cpp:782
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safe_cast(Src s) noexcept
Definition safe_cast.h:19
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
Definition STTx.cpp:791
T ref(T... args)
Note, should be treated as flags that can be | and &.
Definition STBase.h:17
T to_string(T... args)
T value_or(T... args)
T what(T... args)