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 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
237STTx::sign(PublicKey const& publicKey, SecretKey const& secretKey)
238{
239 auto const data = getSigningData(*this);
240
241 auto const sig = ripple::sign(publicKey, secretKey, makeSlice(data));
242
243 setFieldVL(sfTxnSignature, sig);
245}
246
249 RequireFullyCanonicalSig requireCanonicalSig,
250 Rules const& rules) const
251{
252 try
253 {
254 // Determine whether we're single- or multi-signing by looking
255 // at the SigningPubKey. If it's empty we must be
256 // multi-signing. Otherwise we're single-signing.
257 Blob const& signingPubKey = getFieldVL(sfSigningPubKey);
258 return signingPubKey.empty()
259 ? checkMultiSign(requireCanonicalSig, rules)
260 : checkSingleSign(requireCanonicalSig);
261 }
262 catch (std::exception const&)
263 {
264 }
265 return Unexpected("Internal signature check failure.");
266}
267
270 RequireFullyCanonicalSig requireCanonicalSig,
271 Rules const& rules) const
272{
273 try
274 {
275 XRPL_ASSERT(
276 getTxnType() == ttBATCH,
277 "STTx::checkBatchSign : not a batch transaction");
278 if (getTxnType() != ttBATCH)
279 {
280 JLOG(debugLog().fatal()) << "not a batch transaction";
281 return Unexpected("Not a batch transaction.");
282 }
283 STArray const& signers{getFieldArray(sfBatchSigners)};
284 for (auto const& signer : signers)
285 {
286 Blob const& signingPubKey = signer.getFieldVL(sfSigningPubKey);
287 auto const result = signingPubKey.empty()
288 ? checkBatchMultiSign(signer, requireCanonicalSig, rules)
289 : checkBatchSingleSign(signer, requireCanonicalSig);
290
291 if (!result)
292 return result;
293 }
294 return {};
295 }
296 catch (std::exception const& e)
297 {
298 JLOG(debugLog().error())
299 << "Batch signature check failed: " << e.what();
300 }
301 return Unexpected("Internal batch signature check failure.");
302}
303
306{
308 if (!(options & JsonOptions::disable_API_prior_V2))
309 ret[jss::hash] = to_string(getTransactionID());
310 return ret;
311}
312
314STTx::getJson(JsonOptions options, bool binary) const
315{
316 bool const V1 = !(options & JsonOptions::disable_API_prior_V2);
317
318 if (binary)
319 {
321 std::string const dataBin = strHex(s.peekData());
322
323 if (V1)
324 {
326 ret[jss::tx] = dataBin;
327 ret[jss::hash] = to_string(getTransactionID());
328 return ret;
329 }
330 else
331 return Json::Value{dataBin};
332 }
333
335 if (V1)
336 ret[jss::hash] = to_string(getTransactionID());
337
338 return ret;
339}
340
341std::string const&
343{
344 static std::string const sql =
345 "INSERT OR REPLACE INTO Transactions "
346 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, "
347 "TxnMeta)"
348 " VALUES ";
349
350 return sql;
351}
352
354STTx::getMetaSQL(std::uint32_t inLedger, std::string const& escapedMetaData)
355 const
356{
357 Serializer s;
358 add(s);
359 return getMetaSQL(s, inLedger, txnSqlValidated, escapedMetaData);
360}
361
362// VFALCO This could be a free function elsewhere
365 Serializer rawTxn,
366 std::uint32_t inLedger,
367 char status,
368 std::string const& escapedMetaData) const
369{
370 static boost::format bfTrans(
371 "('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
372 std::string rTxn = sqlBlobLiteral(rawTxn.peekData());
373
375 XRPL_ASSERT(format, "ripple::STTx::getMetaSQL : non-null type format");
376
377 return str(
378 boost::format(bfTrans) % to_string(getTransactionID()) %
379 format->getName() % toBase58(getAccountID(sfAccount)) %
380 getFieldU32(sfSequence) % inLedger % status % rTxn % escapedMetaData);
381}
382
385 STObject const& signer,
386 Slice const& data,
387 bool const fullyCanonical)
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 (signer.isFieldPresent(sfSigners))
393 return Unexpected("Cannot both single- and multi-sign.");
394
395 bool validSig = false;
396 try
397 {
398 auto const spk = signer.getFieldVL(sfSigningPubKey);
399 if (publicKeyType(makeSlice(spk)))
400 {
401 Blob const signature = signer.getFieldVL(sfTxnSignature);
402 validSig = verify(
403 PublicKey(makeSlice(spk)),
404 data,
405 makeSlice(signature),
407 }
408 }
409 catch (std::exception const&)
410 {
411 validSig = false;
412 }
413
414 if (!validSig)
415 return Unexpected("Invalid signature.");
416
417 return {};
418}
419
420Expected<void, std::string>
422{
423 auto const data = getSigningData(*this);
424 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
425 (requireCanonicalSig == STTx::RequireFullyCanonicalSig::yes);
426 return singleSignHelper(*this, makeSlice(data), fullyCanonical);
427}
428
431 STObject const& batchSigner,
432 RequireFullyCanonicalSig requireCanonicalSig) const
433{
434 Serializer msg;
436 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
437 (requireCanonicalSig == STTx::RequireFullyCanonicalSig::yes);
438 return singleSignHelper(batchSigner, msg.slice(), fullyCanonical);
439}
440
443 STObject const& signerObj,
444 bool const fullyCanonical,
445 std::function<Serializer(AccountID const&)> makeMsg,
446 Rules const& rules)
447{
448 // Make sure the MultiSigners are present. Otherwise they are not
449 // attempting multi-signing and we just have a bad SigningPubKey.
450 if (!signerObj.isFieldPresent(sfSigners))
451 return Unexpected("Empty SigningPubKey.");
452
453 // We don't allow both an sfSigners and an sfTxnSignature. Both fields
454 // being present would indicate that the transaction is signed both ways.
455 if (signerObj.isFieldPresent(sfTxnSignature))
456 return Unexpected("Cannot both single- and multi-sign.");
457
458 STArray const& signers{signerObj.getFieldArray(sfSigners)};
459
460 // There are well known bounds that the number of signers must be within.
461 if (signers.size() < STTx::minMultiSigners ||
462 signers.size() > STTx::maxMultiSigners(&rules))
463 return Unexpected("Invalid Signers array size.");
464
465 // We also use the sfAccount field inside the loop. Get it once.
466 auto const txnAccountID = signerObj.getAccountID(sfAccount);
467
468 // Signers must be in sorted order by AccountID.
469 AccountID lastAccountID(beast::zero);
470
471 for (auto const& signer : signers)
472 {
473 auto const accountID = signer.getAccountID(sfAccount);
474
475 // The account owner may not multisign for themselves.
476 if (accountID == txnAccountID)
477 return Unexpected("Invalid multisigner.");
478
479 // No duplicate signers allowed.
480 if (lastAccountID == accountID)
481 return Unexpected("Duplicate Signers not allowed.");
482
483 // Accounts must be in order by account ID. No duplicates allowed.
484 if (lastAccountID > accountID)
485 return Unexpected("Unsorted Signers array.");
486
487 // The next signature must be greater than this one.
488 lastAccountID = accountID;
489
490 // Verify the signature.
491 bool validSig = false;
492 try
493 {
494 auto spk = signer.getFieldVL(sfSigningPubKey);
495 if (publicKeyType(makeSlice(spk)))
496 {
497 Blob const signature = signer.getFieldVL(sfTxnSignature);
498 validSig = verify(
499 PublicKey(makeSlice(spk)),
500 makeMsg(accountID).slice(),
501 makeSlice(signature),
503 }
504 }
505 catch (std::exception const&)
506 {
507 // We assume any problem lies with the signature.
508 validSig = false;
509 }
510 if (!validSig)
511 return Unexpected(
512 std::string("Invalid signature on account ") +
513 toBase58(accountID) + ".");
514 }
515 // All signatures verified.
516 return {};
517}
518
519Expected<void, std::string>
521 STObject const& batchSigner,
522 RequireFullyCanonicalSig requireCanonicalSig,
523 Rules const& rules) const
524{
525 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
526 (requireCanonicalSig == RequireFullyCanonicalSig::yes);
527
528 // We can ease the computational load inside the loop a bit by
529 // pre-constructing part of the data that we hash. Fill a Serializer
530 // with the stuff that stays constant from signature to signature.
531 Serializer dataStart;
533 return multiSignHelper(
534 batchSigner,
536 [&dataStart](AccountID const& accountID) mutable -> Serializer {
537 Serializer s = dataStart;
538 finishMultiSigningData(accountID, s);
539 return s;
540 },
541 rules);
542}
543
546 RequireFullyCanonicalSig requireCanonicalSig,
547 Rules const& rules) const
548{
549 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
550 (requireCanonicalSig == RequireFullyCanonicalSig::yes);
551
552 // We can ease the computational load inside the loop a bit by
553 // pre-constructing part of the data that we hash. Fill a Serializer
554 // with the stuff that stays constant from signature to signature.
555 Serializer dataStart = startMultiSigningData(*this);
556 return multiSignHelper(
557 *this,
559 [&dataStart](AccountID const& accountID) mutable -> Serializer {
560 Serializer s = dataStart;
561 finishMultiSigningData(accountID, s);
562 return s;
563 },
564 rules);
565}
566
584{
585 XRPL_ASSERT(
586 getTxnType() == ttBATCH,
587 "STTx::getBatchTransactionIDs : not a batch transaction");
588 XRPL_ASSERT(
589 getFieldArray(sfRawTransactions).size() != 0,
590 "STTx::getBatchTransactionIDs : empty raw transactions");
591 if (batch_txn_ids_.size() != 0)
592 return batch_txn_ids_;
593
594 for (STObject const& rb : getFieldArray(sfRawTransactions))
595 batch_txn_ids_.push_back(rb.getHash(HashPrefix::transactionID));
596
597 XRPL_ASSERT(
598 batch_txn_ids_.size() == getFieldArray(sfRawTransactions).size(),
599 "STTx::getBatchTransactionIDs : batch transaction IDs size mismatch");
600 return batch_txn_ids_;
601}
602
603//------------------------------------------------------------------------------
604
605static bool
606isMemoOkay(STObject const& st, std::string& reason)
607{
608 if (!st.isFieldPresent(sfMemos))
609 return true;
610
611 auto const& memos = st.getFieldArray(sfMemos);
612
613 // The number 2048 is a preallocation hint, not a hard limit
614 // to avoid allocate/copy/free's
615 Serializer s(2048);
616 memos.add(s);
617
618 // FIXME move the memo limit into a config tunable
619 if (s.getDataLength() > 1024)
620 {
621 reason = "The memo exceeds the maximum allowed size.";
622 return false;
623 }
624
625 for (auto const& memo : memos)
626 {
627 auto memoObj = dynamic_cast<STObject const*>(&memo);
628
629 if (!memoObj || (memoObj->getFName() != sfMemo))
630 {
631 reason = "A memo array may contain only Memo objects.";
632 return false;
633 }
634
635 for (auto const& memoElement : *memoObj)
636 {
637 auto const& name = memoElement.getFName();
638
639 if (name != sfMemoType && name != sfMemoData &&
640 name != sfMemoFormat)
641 {
642 reason =
643 "A memo may contain only MemoType, MemoData or "
644 "MemoFormat fields.";
645 return false;
646 }
647
648 // The raw data is stored as hex-octets, which we want to decode.
649 auto optData = strUnHex(memoElement.getText());
650
651 if (!optData)
652 {
653 reason =
654 "The MemoType, MemoData and MemoFormat fields may "
655 "only contain hex-encoded data.";
656 return false;
657 }
658
659 if (name == sfMemoData)
660 continue;
661
662 // The only allowed characters for MemoType and MemoFormat are the
663 // characters allowed in URLs per RFC 3986: alphanumerics and the
664 // following symbols: -._~:/?#[]@!$&'()*+,;=%
665 static constexpr std::array<char, 256> const allowedSymbols = []() {
667
668 std::string_view symbols(
669 "0123456789"
670 "-._~:/?#[]@!$&'()*+,;=%"
671 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
672 "abcdefghijklmnopqrstuvwxyz");
673
674 for (unsigned char c : symbols)
675 a[c] = 1;
676 return a;
677 }();
678
679 for (unsigned char c : *optData)
680 {
681 if (!allowedSymbols[c])
682 {
683 reason =
684 "The MemoType and MemoFormat fields may only "
685 "contain characters that are allowed in URLs "
686 "under RFC 3986.";
687 return false;
688 }
689 }
690 }
691 }
692
693 return true;
694}
695
696// Ensure all account fields are 160-bits
697static bool
699{
700 for (int i = 0; i < st.getCount(); ++i)
701 {
702 auto t = dynamic_cast<STAccount const*>(st.peekAtPIndex(i));
703 if (t && t->isDefault())
704 return false;
705 }
706
707 return true;
708}
709
710static bool
712{
713 auto const txType = tx[~sfTransactionType];
714 if (!txType)
715 return false;
716 if (auto const* item =
717 TxFormats::getInstance().findByType(safe_cast<TxType>(*txType)))
718 {
719 for (auto const& e : item->getSOTemplate())
720 {
721 if (tx.isFieldPresent(e.sField()) && e.supportMPT() != soeMPTNone)
722 {
723 if (auto const& field = tx.peekAtField(e.sField());
724 (field.getSType() == STI_AMOUNT &&
725 static_cast<STAmount const&>(field).holds<MPTIssue>()) ||
726 (field.getSType() == STI_ISSUE &&
727 static_cast<STIssue const&>(field).holds<MPTIssue>()))
728 {
729 if (e.supportMPT() != soeMPTSupported)
730 return true;
731 }
732 }
733 }
734 }
735 return false;
736}
737
738static bool
740{
741 if (!st.isFieldPresent(sfRawTransactions))
742 return true;
743
744 if (st.isFieldPresent(sfBatchSigners) &&
745 st.getFieldArray(sfBatchSigners).size() > maxBatchTxCount)
746 {
747 reason = "Batch Signers array exceeds max entries.";
748 return false;
749 }
750
751 auto const& rawTxns = st.getFieldArray(sfRawTransactions);
752 if (rawTxns.size() > maxBatchTxCount)
753 {
754 reason = "Raw Transactions array exceeds max entries.";
755 return false;
756 }
757 for (STObject raw : rawTxns)
758 {
759 try
760 {
761 TxType const tt =
762 safe_cast<TxType>(raw.getFieldU16(sfTransactionType));
763 if (tt == ttBATCH)
764 {
765 reason = "Raw Transactions may not contain batch transactions.";
766 return false;
767 }
768
769 raw.applyTemplate(getTxFormat(tt)->getSOTemplate());
770 }
771 catch (std::exception const& e)
772 {
773 reason = e.what();
774 return false;
775 }
776 }
777 return true;
778}
779
780bool
782{
783 if (!isMemoOkay(st, reason))
784 return false;
785
786 if (!isAccountFieldOkay(st))
787 {
788 reason = "An account field is invalid.";
789 return false;
790 }
791
792 if (isPseudoTx(st))
793 {
794 reason = "Cannot submit pseudo transactions.";
795 return false;
796 }
797
798 if (invalidMPTAmountInTx(st))
799 {
800 reason = "Amount can not be MPT.";
801 return false;
802 }
803
804 if (!isRawTransactionOkay(st, reason))
805 return false;
806
807 return true;
808}
809
811sterilize(STTx const& stx)
812{
813 Serializer s;
814 stx.add(s);
815 SerialIter sit(s.slice());
817}
818
819bool
821{
822 auto const t = tx[~sfTransactionType];
823
824 if (!t)
825 return false;
826
827 auto const tt = safe_cast<TxType>(*t);
828
829 return tt == ttAMENDMENT || tt == ttFEE || tt == ttUNL_MODIFY;
830}
831
832} // 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:61
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:657
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:651
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:686
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:997
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:609
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:615
int getCount() const
Definition STObject.h:979
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:735
Serializer getSerializer() const
Definition STObject.h:963
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:1010
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:825
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:429
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:954
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:777
std::uint32_t getFlags() const
Definition STObject.cpp:537
boost::container::flat_set< AccountID > getMentionedAccounts() const
Definition STTx.cpp:162
std::vector< uint256 > getBatchTransactionIDs() const
Retrieves a batch of transaction IDs from the STTx.
Definition STTx.cpp:583
uint256 getSigningHash() const
Definition STTx.cpp:197
static std::string const & getMetaSQLInsertReplaceHeader()
Definition STTx.cpp:342
void sign(PublicKey const &publicKey, SecretKey const &secretKey)
Definition STTx.cpp:237
Expected< void, std::string > checkMultiSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
Definition STTx.cpp:545
SeqProxy getSeqProxy() const
Definition STTx.cpp:216
Json::Value getJson(JsonOptions options) const override
Definition STTx.cpp:305
Expected< void, std::string > checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
Definition STTx.cpp:421
Expected< void, std::string > checkBatchSingleSign(STObject const &batchSigner, RequireFullyCanonicalSig requireCanonicalSig) const
Definition STTx.cpp:430
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
Definition STTx.cpp:248
static std::size_t maxMultiSigners(Rules const *rules=0)
Definition STTx.h:57
RequireFullyCanonicalSig
Check the signature.
Definition STTx.h:127
TxType tx_type_
Definition STTx.h:50
std::vector< uint256 > batch_txn_ids_
Definition STTx.h:182
uint256 tid_
Definition STTx.h:49
Expected< void, std::string > checkBatchMultiSign(STObject const &batchSigner, RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
Definition STTx.cpp:520
Blob getSignature() const
Definition STTx.cpp:203
STTx()=delete
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition STTx.cpp:231
TxType getTxnType() const
Definition STTx.h:207
std::string getMetaSQL(std::uint32_t inLedger, std::string const &escapedMetaData) const
Definition STTx.cpp:354
uint256 getTransactionID() const
Definition STTx.h:219
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:269
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:811
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:698
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:820
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:606
static bool isRawTransactionOkay(STObject const &st, std::string &reason)
Definition STTx.cpp:739
SerializedTypeID
Definition SField.h:108
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:711
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
static Expected< void, std::string > singleSignHelper(STObject const &signer, Slice const &data, bool const fullyCanonical)
Definition STTx.cpp:384
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
Expected< void, std::string > multiSignHelper(STObject const &signerObj, bool const fullyCanonical, std::function< Serializer(AccountID const &)> makeMsg, Rules const &rules)
Definition STTx.cpp:442
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:468
@ 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:781
@ 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
@ 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:179
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 what(T... args)