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 ripple {
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 "ripple::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 = ripple::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 /* Placeholder for field that will be added by Lending Protocol
265 if (isFieldPresent(sfCounterpartySignature))
266 {
267 auto const counterSig = getFieldObject(sfCounterpartySignature);
268 if (auto const ret = checkSign(rules, counterSig);
269 !ret)
270 return Unexpected("Counterparty: " + ret.error());
271 }
272 */
273 return {};
274}
275
277STTx::checkBatchSign(Rules const& rules) const
278{
279 try
280 {
281 XRPL_ASSERT(
282 getTxnType() == ttBATCH,
283 "STTx::checkBatchSign : not a batch transaction");
284 if (getTxnType() != ttBATCH)
285 {
286 JLOG(debugLog().fatal()) << "not a batch transaction";
287 return Unexpected("Not a batch transaction.");
288 }
289 STArray const& signers{getFieldArray(sfBatchSigners)};
290 for (auto const& signer : signers)
291 {
292 Blob const& signingPubKey = signer.getFieldVL(sfSigningPubKey);
293 auto const result = signingPubKey.empty()
294 ? checkBatchMultiSign(signer, rules)
295 : checkBatchSingleSign(signer);
296
297 if (!result)
298 return result;
299 }
300 return {};
301 }
302 catch (std::exception const& e)
303 {
304 JLOG(debugLog().error())
305 << "Batch signature check failed: " << e.what();
306 }
307 return Unexpected("Internal batch signature check failure.");
308}
309
312{
314 if (!(options & JsonOptions::disable_API_prior_V2))
315 ret[jss::hash] = to_string(getTransactionID());
316 return ret;
317}
318
320STTx::getJson(JsonOptions options, bool binary) const
321{
322 bool const V1 = !(options & JsonOptions::disable_API_prior_V2);
323
324 if (binary)
325 {
327 std::string const dataBin = strHex(s.peekData());
328
329 if (V1)
330 {
332 ret[jss::tx] = dataBin;
333 ret[jss::hash] = to_string(getTransactionID());
334 return ret;
335 }
336 else
337 return Json::Value{dataBin};
338 }
339
341 if (V1)
342 ret[jss::hash] = to_string(getTransactionID());
343
344 return ret;
345}
346
347std::string const&
349{
350 static std::string const sql =
351 "INSERT OR REPLACE INTO Transactions "
352 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, "
353 "TxnMeta)"
354 " VALUES ";
355
356 return sql;
357}
358
360STTx::getMetaSQL(std::uint32_t inLedger, std::string const& escapedMetaData)
361 const
362{
363 Serializer s;
364 add(s);
365 return getMetaSQL(s, inLedger, txnSqlValidated, escapedMetaData);
366}
367
368// VFALCO This could be a free function elsewhere
371 Serializer rawTxn,
372 std::uint32_t inLedger,
373 char status,
374 std::string const& escapedMetaData) const
375{
376 static boost::format bfTrans(
377 "('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
378 std::string rTxn = sqlBlobLiteral(rawTxn.peekData());
379
381 XRPL_ASSERT(format, "ripple::STTx::getMetaSQL : non-null type format");
382
383 return str(
384 boost::format(bfTrans) % to_string(getTransactionID()) %
385 format->getName() % toBase58(getAccountID(sfAccount)) %
386 getFieldU32(sfSequence) % inLedger % status % rTxn % escapedMetaData);
387}
388
390singleSignHelper(STObject const& sigObject, Slice const& data)
391{
392 // We don't allow both a non-empty sfSigningPubKey and an sfSigners.
393 // That would allow the transaction to be signed two ways. So if both
394 // fields are present the signature is invalid.
395 if (sigObject.isFieldPresent(sfSigners))
396 return Unexpected("Cannot both single- and multi-sign.");
397
398 bool validSig = false;
399 try
400 {
401 auto const spk = sigObject.getFieldVL(sfSigningPubKey);
402 if (publicKeyType(makeSlice(spk)))
403 {
404 Blob const signature = sigObject.getFieldVL(sfTxnSignature);
405 validSig =
406 verify(PublicKey(makeSlice(spk)), data, 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>
421STTx::checkSingleSign(STObject const& sigObject) const
422{
423 auto const data = getSigningData(*this);
424 return singleSignHelper(sigObject, makeSlice(data));
425}
426
428STTx::checkBatchSingleSign(STObject const& batchSigner) const
429{
430 Serializer msg;
432 return singleSignHelper(batchSigner, msg.slice());
433}
434
437 STObject const& sigObject,
438 std::optional<AccountID> txnAccountID,
439 std::function<Serializer(AccountID const&)> makeMsg,
440 Rules const& rules)
441{
442 // Make sure the MultiSigners are present. Otherwise they are not
443 // attempting multi-signing and we just have a bad SigningPubKey.
444 if (!sigObject.isFieldPresent(sfSigners))
445 return Unexpected("Empty SigningPubKey.");
446
447 // We don't allow both an sfSigners and an sfTxnSignature. Both fields
448 // being present would indicate that the transaction is signed both ways.
449 if (sigObject.isFieldPresent(sfTxnSignature))
450 return Unexpected("Cannot both single- and multi-sign.");
451
452 STArray const& signers{sigObject.getFieldArray(sfSigners)};
453
454 // There are well known bounds that the number of signers must be within.
455 if (signers.size() < STTx::minMultiSigners ||
456 signers.size() > STTx::maxMultiSigners)
457 return Unexpected("Invalid Signers array size.");
458
459 // Signers must be in sorted order by AccountID.
460 AccountID lastAccountID(beast::zero);
461
462 for (auto const& signer : signers)
463 {
464 auto const accountID = signer.getAccountID(sfAccount);
465
466 // The account owner may not usually multisign for themselves.
467 // If they can, txnAccountID will be unseated, which is not equal to any
468 // value.
469 if (txnAccountID == accountID)
470 return Unexpected("Invalid multisigner.");
471
472 // No duplicate signers allowed.
473 if (lastAccountID == accountID)
474 return Unexpected("Duplicate Signers not allowed.");
475
476 // Accounts must be in order by account ID. No duplicates allowed.
477 if (lastAccountID > accountID)
478 return Unexpected("Unsorted Signers array.");
479
480 // The next signature must be greater than this one.
481 lastAccountID = accountID;
482
483 // Verify the signature.
484 bool validSig = false;
486 try
487 {
488 auto spk = signer.getFieldVL(sfSigningPubKey);
489 if (publicKeyType(makeSlice(spk)))
490 {
491 Blob const signature = signer.getFieldVL(sfTxnSignature);
492 validSig = verify(
493 PublicKey(makeSlice(spk)),
494 makeMsg(accountID).slice(),
495 makeSlice(signature));
496 }
497 }
498 catch (std::exception const& e)
499 {
500 // We assume any problem lies with the signature.
501 validSig = false;
502 errorWhat = e.what();
503 }
504 if (!validSig)
505 return Unexpected(
506 std::string("Invalid signature on account ") +
507 toBase58(accountID) + errorWhat.value_or("") + ".");
508 }
509 // All signatures verified.
510 return {};
511}
512
513Expected<void, std::string>
514STTx::checkBatchMultiSign(STObject const& batchSigner, Rules const& rules) const
515{
516 // We can ease the computational load inside the loop a bit by
517 // pre-constructing part of the data that we hash. Fill a Serializer
518 // with the stuff that stays constant from signature to signature.
519 Serializer dataStart;
521 return multiSignHelper(
522 batchSigner,
524 [&dataStart](AccountID const& accountID) -> Serializer {
525 Serializer s = dataStart;
526 finishMultiSigningData(accountID, s);
527 return s;
528 },
529 rules);
530}
531
533STTx::checkMultiSign(Rules const& rules, STObject const& sigObject) const
534{
535 // Used inside the loop in multiSignHelper to enforce that
536 // the account owner may not multisign for themselves.
537 auto const txnAccountID = &sigObject != this
540
541 // We can ease the computational load inside the loop a bit by
542 // pre-constructing part of the data that we hash. Fill a Serializer
543 // with the stuff that stays constant from signature to signature.
544 Serializer dataStart = startMultiSigningData(*this);
545 return multiSignHelper(
546 sigObject,
547 txnAccountID,
548 [&dataStart](AccountID const& accountID) -> Serializer {
549 Serializer s = dataStart;
550 finishMultiSigningData(accountID, s);
551 return s;
552 },
553 rules);
554}
555
573{
574 XRPL_ASSERT(
575 getTxnType() == ttBATCH,
576 "STTx::getBatchTransactionIDs : not a batch transaction");
577 XRPL_ASSERT(
578 getFieldArray(sfRawTransactions).size() != 0,
579 "STTx::getBatchTransactionIDs : empty raw transactions");
580
581 // The list of inner ids is built once, then reused on subsequent calls.
582 // After the list is built, it must always have the same size as the array
583 // `sfRawTransactions`. The assert below verifies that.
584 if (batchTxnIds_.size() == 0)
585 {
586 for (STObject const& rb : getFieldArray(sfRawTransactions))
587 batchTxnIds_.push_back(rb.getHash(HashPrefix::transactionID));
588 }
589
590 XRPL_ASSERT(
591 batchTxnIds_.size() == getFieldArray(sfRawTransactions).size(),
592 "STTx::getBatchTransactionIDs : batch transaction IDs size mismatch");
593 return batchTxnIds_;
594}
595
596//------------------------------------------------------------------------------
597
598static bool
599isMemoOkay(STObject const& st, std::string& reason)
600{
601 if (!st.isFieldPresent(sfMemos))
602 return true;
603
604 auto const& memos = st.getFieldArray(sfMemos);
605
606 // The number 2048 is a preallocation hint, not a hard limit
607 // to avoid allocate/copy/free's
608 Serializer s(2048);
609 memos.add(s);
610
611 // FIXME move the memo limit into a config tunable
612 if (s.getDataLength() > 1024)
613 {
614 reason = "The memo exceeds the maximum allowed size.";
615 return false;
616 }
617
618 for (auto const& memo : memos)
619 {
620 auto memoObj = dynamic_cast<STObject const*>(&memo);
621
622 if (!memoObj || (memoObj->getFName() != sfMemo))
623 {
624 reason = "A memo array may contain only Memo objects.";
625 return false;
626 }
627
628 for (auto const& memoElement : *memoObj)
629 {
630 auto const& name = memoElement.getFName();
631
632 if (name != sfMemoType && name != sfMemoData &&
633 name != sfMemoFormat)
634 {
635 reason =
636 "A memo may contain only MemoType, MemoData or "
637 "MemoFormat fields.";
638 return false;
639 }
640
641 // The raw data is stored as hex-octets, which we want to decode.
642 auto optData = strUnHex(memoElement.getText());
643
644 if (!optData)
645 {
646 reason =
647 "The MemoType, MemoData and MemoFormat fields may "
648 "only contain hex-encoded data.";
649 return false;
650 }
651
652 if (name == sfMemoData)
653 continue;
654
655 // The only allowed characters for MemoType and MemoFormat are the
656 // characters allowed in URLs per RFC 3986: alphanumerics and the
657 // following symbols: -._~:/?#[]@!$&'()*+,;=%
658 static constexpr std::array<char, 256> const allowedSymbols = []() {
660
661 std::string_view symbols(
662 "0123456789"
663 "-._~:/?#[]@!$&'()*+,;=%"
664 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
665 "abcdefghijklmnopqrstuvwxyz");
666
667 for (unsigned char c : symbols)
668 a[c] = 1;
669 return a;
670 }();
671
672 for (unsigned char c : *optData)
673 {
674 if (!allowedSymbols[c])
675 {
676 reason =
677 "The MemoType and MemoFormat fields may only "
678 "contain characters that are allowed in URLs "
679 "under RFC 3986.";
680 return false;
681 }
682 }
683 }
684 }
685
686 return true;
687}
688
689// Ensure all account fields are 160-bits
690static bool
692{
693 for (int i = 0; i < st.getCount(); ++i)
694 {
695 auto t = dynamic_cast<STAccount const*>(st.peekAtPIndex(i));
696 if (t && t->isDefault())
697 return false;
698 }
699
700 return true;
701}
702
703static bool
705{
706 auto const txType = tx[~sfTransactionType];
707 if (!txType)
708 return false;
709 if (auto const* item =
710 TxFormats::getInstance().findByType(safe_cast<TxType>(*txType)))
711 {
712 for (auto const& e : item->getSOTemplate())
713 {
714 if (tx.isFieldPresent(e.sField()) && e.supportMPT() != soeMPTNone)
715 {
716 if (auto const& field = tx.peekAtField(e.sField());
717 (field.getSType() == STI_AMOUNT &&
718 static_cast<STAmount const&>(field).holds<MPTIssue>()) ||
719 (field.getSType() == STI_ISSUE &&
720 static_cast<STIssue const&>(field).holds<MPTIssue>()))
721 {
722 if (e.supportMPT() != soeMPTSupported)
723 return true;
724 }
725 }
726 }
727 }
728 return false;
729}
730
731static bool
733{
734 if (!st.isFieldPresent(sfRawTransactions))
735 return true;
736
737 if (st.isFieldPresent(sfBatchSigners) &&
738 st.getFieldArray(sfBatchSigners).size() > maxBatchTxCount)
739 {
740 reason = "Batch Signers array exceeds max entries.";
741 return false;
742 }
743
744 auto const& rawTxns = st.getFieldArray(sfRawTransactions);
745 if (rawTxns.size() > maxBatchTxCount)
746 {
747 reason = "Raw Transactions array exceeds max entries.";
748 return false;
749 }
750 for (STObject raw : rawTxns)
751 {
752 try
753 {
754 TxType const tt =
755 safe_cast<TxType>(raw.getFieldU16(sfTransactionType));
756 if (tt == ttBATCH)
757 {
758 reason = "Raw Transactions may not contain batch transactions.";
759 return false;
760 }
761
762 raw.applyTemplate(getTxFormat(tt)->getSOTemplate());
763 }
764 catch (std::exception const& e)
765 {
766 reason = e.what();
767 return false;
768 }
769 }
770 return true;
771}
772
773bool
775{
776 if (!isMemoOkay(st, reason))
777 return false;
778
779 if (!isAccountFieldOkay(st))
780 {
781 reason = "An account field is invalid.";
782 return false;
783 }
784
785 if (isPseudoTx(st))
786 {
787 reason = "Cannot submit pseudo transactions.";
788 return false;
789 }
790
791 if (invalidMPTAmountInTx(st))
792 {
793 reason = "Amount can not be MPT.";
794 return false;
795 }
796
797 if (!isRawTransactionOkay(st, reason))
798 return false;
799
800 return true;
801}
802
804sterilize(STTx const& stx)
805{
806 Serializer s;
807 stx.add(s);
808 SerialIter sit(s.slice());
810}
811
812bool
814{
815 auto const t = tx[~sfTransactionType];
816
817 if (!t)
818 return false;
819
820 auto const tt = safe_cast<TxType>(*t);
821
822 return tt == ttAMENDMENT || tt == ttFEE || tt == ttUNL_MODIFY;
823}
824
825} // namespace ripple
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
void applyTemplate(SOTemplate const &type)
Definition STObject.cpp:153
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:644
AccountID getAccountID(SField const &field) const
Definition STObject.cpp:638
STArray const & getFieldArray(SField const &field) const
Definition STObject.cpp:683
STBase const * peekAtPIndex(int offset) const
Definition STObject.h:987
std::uint16_t getFieldU16(SField const &field) const
Definition STObject.cpp:590
std::uint32_t getFieldU32(SField const &field) const
Definition STObject.cpp:596
STObject & peekFieldObject(SField const &field)
Definition STObject.cpp:476
int getCount() const
Definition STObject.h:969
void setFieldU16(SField const &field, std::uint16_t)
Definition STObject.cpp:732
Serializer getSerializer() const
Definition STObject.h:953
void set(SOTemplate const &)
Definition STObject.cpp:137
void add(Serializer &s) const override
Definition STObject.cpp:122
uint256 getSigningHash(HashPrefix prefix) const
Definition STObject.cpp:385
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
Definition STObject.h:1000
uint256 getHash(HashPrefix prefix) const
Definition STObject.cpp:376
std::string getFullText() const override
Definition STObject.cpp:291
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:465
Json::Value getJson(JsonOptions=JsonOptions::none) const override
Definition STObject.cpp:834
STBase const & peekAtField(SField const &field) const
Definition STObject.cpp:410
void addWithoutSigningFields(Serializer &s) const
Definition STObject.h:944
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:780
std::uint32_t getFlags() const
Definition STObject.cpp:518
boost::container::flat_set< AccountID > getMentionedAccounts() const
Definition STTx.cpp:143
uint256 getSigningHash() const
Definition STTx.cpp:178
static std::string const & getMetaSQLInsertReplaceHeader()
Definition STTx.cpp:348
std::vector< uint256 > batchTxnIds_
Definition STTx.h:162
SeqProxy getSeqProxy() const
Definition STTx.cpp:197
static constexpr std::size_t minMultiSigners
Definition STTx.h:34
Json::Value getJson(JsonOptions options) const override
Definition STTx.cpp:311
std::vector< uint256 > const & getBatchTransactionIDs() const
Retrieves a batch of transaction IDs from the STTx.
Definition STTx.cpp:572
STBase * move(std::size_t n, void *buf) override
Definition STTx.cpp:119
Expected< void, std::string > checkBatchMultiSign(STObject const &batchSigner, Rules const &rules) const
Definition STTx.cpp:514
Expected< void, std::string > checkBatchSingleSign(STObject const &batchSigner) const
Definition STTx.cpp:428
static constexpr std::size_t maxMultiSigners
Definition STTx.h:35
Expected< void, std::string > checkBatchSign(Rules const &rules) const
Definition STTx.cpp:277
TxType tx_type_
Definition STTx.h:31
uint256 tid_
Definition STTx.h:30
Blob getSignature() const
Definition STTx.h:66
Expected< void, std::string > checkSingleSign(STObject const &sigObject) const
Definition STTx.cpp:421
Expected< void, std::string > checkMultiSign(Rules const &rules, STObject const &sigObject) const
Definition STTx.cpp:533
STTx()=delete
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition STTx.cpp:212
void sign(PublicKey const &publicKey, SecretKey const &secretKey, std::optional< std::reference_wrapper< SField const > > signatureTarget={})
Definition STTx.cpp:218
TxType getTxnType() const
Definition STTx.h:187
std::string getMetaSQL(std::uint32_t inLedger, std::string const &escapedMetaData) const
Definition STTx.cpp:360
Expected< void, std::string > checkSign(Rules const &rules) const
Check the signature.
Definition STTx.cpp:259
uint256 getTransactionID() const
Definition STTx.h:199
SerializedTypeID getSType() const override
Definition STTx.cpp:126
std::string getFullText() const override
Definition STTx.cpp:132
STBase * copy(std::size_t n, void *buf) const override
Definition STTx.cpp:113
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:357
Slice slice() const noexcept
Definition Serializer.h:47
Blob const & peekData() const
Definition Serializer.h:183
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
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
static Expected< void, std::string > singleSignHelper(STObject const &sigObject, Slice const &data)
Definition STTx.cpp:390
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition STTx.cpp:804
bool isXRP(AccountID const &c)
Definition AccountID.h:71
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
static bool isAccountFieldOkay(STObject const &st)
Definition STTx.cpp:691
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig) noexcept
Verify a signature on a message.
void finishMultiSigningData(AccountID const &signingID, Serializer &s)
Definition Sign.h:65
TxType
Transaction type identifiers.
Definition TxFormats.h:38
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
Definition STTx.cpp:813
Serializer startMultiSigningData(STObject const &obj)
Break the multi-signing hash computation into 2 parts for optimization.
Definition Sign.cpp:85
base_uint< 256 > uint256
Definition base_uint.h:539
static bool isMemoOkay(STObject const &st, std::string &reason)
Definition STTx.cpp:599
Expected< void, std::string > multiSignHelper(STObject const &sigObject, std::optional< AccountID > txnAccountID, std::function< Serializer(AccountID const &)> makeMsg, Rules const &rules)
Definition STTx.cpp:436
static bool isRawTransactionOkay(STObject const &st, std::string &reason)
Definition STTx.cpp:732
SerializedTypeID
Definition SField.h:91
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:22
std::size_t constexpr txMinSizeBytes
Protocol specific constants.
Definition Protocol.h:22
static auto getTxFormat(TxType type)
Definition STTx.cpp:57
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:704
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:11
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
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:457
@ txnSqlValidated
Definition STTx.h:23
std::vector< unsigned char > Blob
Storage for linear binary data.
Definition Blob.h:11
static Blob getSigningData(STTx const &that)
Definition STTx.cpp:169
bool passesLocalChecks(STObject const &st, std::string &)
Definition STTx.cpp:774
@ soeMPTNone
Definition SOTemplate.h:24
@ soeMPTSupported
Definition SOTemplate.h:24
std::size_t constexpr txMaxSizeBytes
Largest legal byte size of a transaction.
Definition Protocol.h:25
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
@ 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:163
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:18
T to_string(T... args)
T value_or(T... args)
T what(T... args)