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