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