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