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/Slice.h>
23#include <xrpl/basics/StringUtilities.h>
24#include <xrpl/basics/base_uint.h>
25#include <xrpl/basics/contract.h>
26#include <xrpl/basics/safe_cast.h>
27#include <xrpl/basics/strHex.h>
28#include <xrpl/beast/utility/Zero.h>
29#include <xrpl/beast/utility/instrumentation.h>
30#include <xrpl/json/json_value.h>
31#include <xrpl/protocol/AccountID.h>
32#include <xrpl/protocol/HashPrefix.h>
33#include <xrpl/protocol/MPTIssue.h>
34#include <xrpl/protocol/Protocol.h>
35#include <xrpl/protocol/PublicKey.h>
36#include <xrpl/protocol/Rules.h>
37#include <xrpl/protocol/SField.h>
38#include <xrpl/protocol/SOTemplate.h>
39#include <xrpl/protocol/STAccount.h>
40#include <xrpl/protocol/STAmount.h>
41#include <xrpl/protocol/STArray.h>
42#include <xrpl/protocol/STBase.h>
43#include <xrpl/protocol/STObject.h>
44#include <xrpl/protocol/STTx.h>
45#include <xrpl/protocol/SecretKey.h>
46#include <xrpl/protocol/SeqProxy.h>
47#include <xrpl/protocol/Serializer.h>
48#include <xrpl/protocol/Sign.h>
49#include <xrpl/protocol/TxFlags.h>
50#include <xrpl/protocol/TxFormats.h>
51#include <xrpl/protocol/jss.h>
52
53#include <boost/container/flat_set.hpp>
54#include <boost/format/format_fwd.hpp>
55#include <boost/format/free_funcs.hpp>
56
57#include <array>
58#include <cstddef>
59#include <cstdint>
60#include <exception>
61#include <functional>
62#include <memory>
63#include <optional>
64#include <stdexcept>
65#include <string>
66#include <string_view>
67#include <type_traits>
68#include <utility>
69
70namespace ripple {
71
72static auto
74{
75 auto format = TxFormats::getInstance().findByType(type);
76
77 if (format == nullptr)
78 {
79 Throw<std::runtime_error>(
80 "Invalid transaction type " +
82 }
83
84 return format;
85}
86
87STTx::STTx(STObject&& object) : STObject(std::move(object))
88{
89 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
90 applyTemplate(getTxFormat(tx_type_)->getSOTemplate()); // may throw
92}
93
94STTx::STTx(SerialIter& sit) : STObject(sfTransaction)
95{
96 int length = sit.getBytesLeft();
97
98 if ((length < txMinSizeBytes) || (length > txMaxSizeBytes))
99 Throw<std::runtime_error>("Transaction length invalid");
100
101 if (set(sit))
102 Throw<std::runtime_error>("Transaction contains an object terminator");
103
104 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
105
106 applyTemplate(getTxFormat(tx_type_)->getSOTemplate()); // May throw
108}
109
110STTx::STTx(TxType type, std::function<void(STObject&)> assembler)
111 : STObject(sfTransaction)
112{
113 auto format = getTxFormat(type);
114
115 set(format->getSOTemplate());
116 setFieldU16(sfTransactionType, format->getType());
117
118 assembler(*this);
119
120 tx_type_ = safe_cast<TxType>(getFieldU16(sfTransactionType));
121
122 if (tx_type_ != type)
123 LogicError("Transaction type was mutated during assembly");
124
126}
127
128STBase*
129STTx::copy(std::size_t n, void* buf) const
130{
131 return emplace(n, buf, *this);
132}
133
134STBase*
136{
137 return emplace(n, buf, std::move(*this));
138}
139
140// STObject functions.
143{
144 return STI_TRANSACTION;
145}
146
149{
150 std::string ret = "\"";
151 ret += to_string(getTransactionID());
152 ret += "\" = {";
153 ret += STObject::getFullText();
154 ret += "}";
155 return ret;
156}
157
158boost::container::flat_set<AccountID>
160{
161 boost::container::flat_set<AccountID> list;
162
163 for (auto const& it : *this)
164 {
165 if (auto sacc = dynamic_cast<STAccount const*>(&it))
166 {
167 XRPL_ASSERT(
168 !sacc->isDefault(),
169 "ripple::STTx::getMentionedAccounts : account is set");
170 if (!sacc->isDefault())
171 list.insert(sacc->value());
172 }
173 else if (auto samt = dynamic_cast<STAmount const*>(&it))
174 {
175 auto const& issuer = samt->getIssuer();
176 if (!isXRP(issuer))
177 list.insert(issuer);
178 }
179 }
180
181 return list;
182}
183
184static Blob
186{
187 Serializer s;
190 return s.getData();
191}
192
195{
197}
198
199Blob
201{
202 try
203 {
204 return getFieldVL(sfTxnSignature);
205 }
206 catch (std::exception const&)
207 {
208 return Blob();
209 }
210}
211
214{
215 std::uint32_t const seq{getFieldU32(sfSequence)};
216 if (seq != 0)
217 return SeqProxy::sequence(seq);
218
219 std::optional<std::uint32_t> const ticketSeq{operator[](~sfTicketSequence)};
220 if (!ticketSeq)
221 // No TicketSequence specified. Return the Sequence, whatever it is.
222 return SeqProxy::sequence(seq);
223
224 return SeqProxy{SeqProxy::ticket, *ticketSeq};
225}
226
229{
230 return getSeqProxy().value();
231}
232
233void
234STTx::sign(PublicKey const& publicKey, SecretKey const& secretKey)
235{
236 auto const data = getSigningData(*this);
237
238 auto const sig = ripple::sign(publicKey, secretKey, makeSlice(data));
239
240 setFieldVL(sfTxnSignature, sig);
242}
243
246 RequireFullyCanonicalSig requireCanonicalSig,
247 Rules const& rules) const
248{
249 try
250 {
251 // Determine whether we're single- or multi-signing by looking
252 // at the SigningPubKey. If it's empty we must be
253 // multi-signing. Otherwise we're single-signing.
254 Blob const& signingPubKey = getFieldVL(sfSigningPubKey);
255 return signingPubKey.empty()
256 ? checkMultiSign(requireCanonicalSig, rules)
257 : checkSingleSign(requireCanonicalSig);
258 }
259 catch (std::exception const&)
260 {
261 }
262 return Unexpected("Internal signature check failure.");
263}
264
267{
269 if (!(options & JsonOptions::disable_API_prior_V2))
270 ret[jss::hash] = to_string(getTransactionID());
271 return ret;
272}
273
275STTx::getJson(JsonOptions options, bool binary) const
276{
277 bool const V1 = !(options & JsonOptions::disable_API_prior_V2);
278
279 if (binary)
280 {
282 std::string const dataBin = strHex(s.peekData());
283
284 if (V1)
285 {
287 ret[jss::tx] = dataBin;
288 ret[jss::hash] = to_string(getTransactionID());
289 return ret;
290 }
291 else
292 return Json::Value{dataBin};
293 }
294
296 if (V1)
297 ret[jss::hash] = to_string(getTransactionID());
298
299 return ret;
300}
301
302std::string const&
304{
305 static std::string const sql =
306 "INSERT OR REPLACE INTO Transactions "
307 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, "
308 "TxnMeta)"
309 " VALUES ";
310
311 return sql;
312}
313
315STTx::getMetaSQL(std::uint32_t inLedger, std::string const& escapedMetaData)
316 const
317{
318 Serializer s;
319 add(s);
320 return getMetaSQL(s, inLedger, txnSqlValidated, escapedMetaData);
321}
322
323// VFALCO This could be a free function elsewhere
326 Serializer rawTxn,
327 std::uint32_t inLedger,
328 char status,
329 std::string const& escapedMetaData) const
330{
331 static boost::format bfTrans(
332 "('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
333 std::string rTxn = sqlBlobLiteral(rawTxn.peekData());
334
336 XRPL_ASSERT(format, "ripple::STTx::getMetaSQL : non-null type format");
337
338 return str(
339 boost::format(bfTrans) % to_string(getTransactionID()) %
340 format->getName() % toBase58(getAccountID(sfAccount)) %
341 getFieldU32(sfSequence) % inLedger % status % rTxn % escapedMetaData);
342}
343
346{
347 // We don't allow both a non-empty sfSigningPubKey and an sfSigners.
348 // That would allow the transaction to be signed two ways. So if both
349 // fields are present the signature is invalid.
350 if (isFieldPresent(sfSigners))
351 return Unexpected("Cannot both single- and multi-sign.");
352
353 bool validSig = false;
354 try
355 {
356 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
357 (requireCanonicalSig == RequireFullyCanonicalSig::yes);
358
359 auto const spk = getFieldVL(sfSigningPubKey);
360
361 if (publicKeyType(makeSlice(spk)))
362 {
363 Blob const signature = getFieldVL(sfTxnSignature);
364 Blob const data = getSigningData(*this);
365
366 validSig = verify(
367 PublicKey(makeSlice(spk)),
368 makeSlice(data),
369 makeSlice(signature),
371 }
372 }
373 catch (std::exception const&)
374 {
375 // Assume it was a signature failure.
376 validSig = false;
377 }
378 if (validSig == false)
379 return Unexpected("Invalid signature.");
380 // Signature was verified.
381 return {};
382}
383
386 RequireFullyCanonicalSig requireCanonicalSig,
387 Rules const& rules) const
388{
389 // Make sure the MultiSigners are present. Otherwise they are not
390 // attempting multi-signing and we just have a bad SigningPubKey.
391 if (!isFieldPresent(sfSigners))
392 return Unexpected("Empty SigningPubKey.");
393
394 // We don't allow both an sfSigners and an sfTxnSignature. Both fields
395 // being present would indicate that the transaction is signed both ways.
396 if (isFieldPresent(sfTxnSignature))
397 return Unexpected("Cannot both single- and multi-sign.");
398
399 STArray const& signers{getFieldArray(sfSigners)};
400
401 // There are well known bounds that the number of signers must be within.
402 if (signers.size() < minMultiSigners ||
403 signers.size() > maxMultiSigners(&rules))
404 return Unexpected("Invalid Signers array size.");
405
406 // We can ease the computational load inside the loop a bit by
407 // pre-constructing part of the data that we hash. Fill a Serializer
408 // with the stuff that stays constant from signature to signature.
409 Serializer const dataStart{startMultiSigningData(*this)};
410
411 // We also use the sfAccount field inside the loop. Get it once.
412 auto const txnAccountID = getAccountID(sfAccount);
413
414 // Determine whether signatures must be full canonical.
415 bool const fullyCanonical = (getFlags() & tfFullyCanonicalSig) ||
416 (requireCanonicalSig == RequireFullyCanonicalSig::yes);
417
418 // Signers must be in sorted order by AccountID.
419 AccountID lastAccountID(beast::zero);
420
421 for (auto const& signer : signers)
422 {
423 auto const accountID = signer.getAccountID(sfAccount);
424
425 // The account owner may not multisign for themselves.
426 if (accountID == txnAccountID)
427 return Unexpected("Invalid multisigner.");
428
429 // No duplicate signers allowed.
430 if (lastAccountID == accountID)
431 return Unexpected("Duplicate Signers not allowed.");
432
433 // Accounts must be in order by account ID. No duplicates allowed.
434 if (lastAccountID > accountID)
435 return Unexpected("Unsorted Signers array.");
436
437 // The next signature must be greater than this one.
438 lastAccountID = accountID;
439
440 // Verify the signature.
441 bool validSig = false;
442 try
443 {
444 Serializer s = dataStart;
445 finishMultiSigningData(accountID, s);
446
447 auto spk = signer.getFieldVL(sfSigningPubKey);
448
449 if (publicKeyType(makeSlice(spk)))
450 {
451 Blob const signature = signer.getFieldVL(sfTxnSignature);
452
453 validSig = verify(
454 PublicKey(makeSlice(spk)),
455 s.slice(),
456 makeSlice(signature),
458 }
459 }
460 catch (std::exception const&)
461 {
462 // We assume any problem lies with the signature.
463 validSig = false;
464 }
465 if (!validSig)
466 return Unexpected(
467 std::string("Invalid signature on account ") +
468 toBase58(accountID) + ".");
469 }
470 // All signatures verified.
471 return {};
472}
473
474//------------------------------------------------------------------------------
475
476static bool
477isMemoOkay(STObject const& st, std::string& reason)
478{
479 if (!st.isFieldPresent(sfMemos))
480 return true;
481
482 auto const& memos = st.getFieldArray(sfMemos);
483
484 // The number 2048 is a preallocation hint, not a hard limit
485 // to avoid allocate/copy/free's
486 Serializer s(2048);
487 memos.add(s);
488
489 // FIXME move the memo limit into a config tunable
490 if (s.getDataLength() > 1024)
491 {
492 reason = "The memo exceeds the maximum allowed size.";
493 return false;
494 }
495
496 for (auto const& memo : memos)
497 {
498 auto memoObj = dynamic_cast<STObject const*>(&memo);
499
500 if (!memoObj || (memoObj->getFName() != sfMemo))
501 {
502 reason = "A memo array may contain only Memo objects.";
503 return false;
504 }
505
506 for (auto const& memoElement : *memoObj)
507 {
508 auto const& name = memoElement.getFName();
509
510 if (name != sfMemoType && name != sfMemoData &&
511 name != sfMemoFormat)
512 {
513 reason =
514 "A memo may contain only MemoType, MemoData or "
515 "MemoFormat fields.";
516 return false;
517 }
518
519 // The raw data is stored as hex-octets, which we want to decode.
520 auto optData = strUnHex(memoElement.getText());
521
522 if (!optData)
523 {
524 reason =
525 "The MemoType, MemoData and MemoFormat fields may "
526 "only contain hex-encoded data.";
527 return false;
528 }
529
530 if (name == sfMemoData)
531 continue;
532
533 // The only allowed characters for MemoType and MemoFormat are the
534 // characters allowed in URLs per RFC 3986: alphanumerics and the
535 // following symbols: -._~:/?#[]@!$&'()*+,;=%
536 static constexpr std::array<char, 256> const allowedSymbols = []() {
538
539 std::string_view symbols(
540 "0123456789"
541 "-._~:/?#[]@!$&'()*+,;=%"
542 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
543 "abcdefghijklmnopqrstuvwxyz");
544
545 for (char c : symbols)
546 a[c] = 1;
547 return a;
548 }();
549
550 for (auto c : *optData)
551 {
552 if (!allowedSymbols[c])
553 {
554 reason =
555 "The MemoType and MemoFormat fields may only "
556 "contain characters that are allowed in URLs "
557 "under RFC 3986.";
558 return false;
559 }
560 }
561 }
562 }
563
564 return true;
565}
566
567// Ensure all account fields are 160-bits
568static bool
570{
571 for (int i = 0; i < st.getCount(); ++i)
572 {
573 auto t = dynamic_cast<STAccount const*>(st.peekAtPIndex(i));
574 if (t && t->isDefault())
575 return false;
576 }
577
578 return true;
579}
580
581static bool
583{
584 auto const txType = tx[~sfTransactionType];
585 if (!txType)
586 return false;
587 if (auto const* item =
588 TxFormats::getInstance().findByType(safe_cast<TxType>(*txType)))
589 {
590 for (auto const& e : item->getSOTemplate())
591 {
592 if (tx.isFieldPresent(e.sField()) && e.supportMPT() != soeMPTNone)
593 {
594 if (auto const& field = tx.peekAtField(e.sField());
595 (field.getSType() == STI_AMOUNT &&
596 static_cast<STAmount const&>(field).holds<MPTIssue>()) ||
597 (field.getSType() == STI_ISSUE &&
598 static_cast<STIssue const&>(field).holds<MPTIssue>()))
599 {
600 if (e.supportMPT() != soeMPTSupported)
601 return true;
602 }
603 }
604 }
605 }
606 return false;
607}
608
609bool
611{
612 if (!isMemoOkay(st, reason))
613 return false;
614
615 if (!isAccountFieldOkay(st))
616 {
617 reason = "An account field is invalid.";
618 return false;
619 }
620
621 if (isPseudoTx(st))
622 {
623 reason = "Cannot submit pseudo transactions.";
624 return false;
625 }
626
627 if (invalidMPTAmountInTx(st))
628 {
629 reason = "Amount can not be MPT.";
630 return false;
631 }
632
633 return true;
634}
635
637sterilize(STTx const& stx)
638{
639 Serializer s;
640 stx.add(s);
641 SerialIter sit(s.slice());
642 return std::make_shared<STTx const>(std::ref(sit));
643}
644
645bool
647{
648 auto t = tx[~sfTransactionType];
649 if (!t)
650 return false;
651 auto tt = safe_cast<TxType>(*t);
652 return tt == ttAMENDMENT || tt == ttFEE || tt == ttUNL_MODIFY;
653}
654
655} // namespace ripple
Represents a JSON value.
Definition: json_value.h:150
UInt size() const
Number of values in array or object.
Definition: json_value.cpp:719
Item const * findByType(KeyType type) const
Retrieve a format based on its type.
Definition: KnownFormats.h:129
A public key.
Definition: PublicKey.h:62
Rules controlling protocol behavior.
Definition: Rules.h:35
constexpr bool holds() const noexcept
Definition: STAmount.h:465
A type which can be exported to a well known binary format.
Definition: STBase.h:136
static STBase * emplace(std::size_t n, void *buf, T &&val)
Definition: STBase.h:234
bool holds() const
Definition: STIssue.h:118
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:159
uint256 getSigningHash() const
Definition: STTx.cpp:194
static std::string const & getMetaSQLInsertReplaceHeader()
Definition: STTx.cpp:303
void sign(PublicKey const &publicKey, SecretKey const &secretKey)
Definition: STTx.cpp:234
Expected< void, std::string > checkMultiSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
Definition: STTx.cpp:385
SeqProxy getSeqProxy() const
Definition: STTx.cpp:213
Json::Value getJson(JsonOptions options) const override
Definition: STTx.cpp:266
Expected< void, std::string > checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
Definition: STTx.cpp:345
STBase * move(std::size_t n, void *buf) override
Definition: STTx.cpp:135
static std::size_t const minMultiSigners
Definition: STTx.h:53
Expected< void, std::string > checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
Definition: STTx.cpp:245
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
uint256 tid_
Definition: STTx.h:49
Blob getSignature() const
Definition: STTx.cpp:200
STTx()=delete
std::uint32_t getSeqValue() const
Returns the first non-zero value of (Sequence, TicketSequence).
Definition: STTx.cpp:228
std::string getMetaSQL(std::uint32_t inLedger, std::string const &escapedMetaData) const
Definition: STTx.cpp:315
uint256 getTransactionID() const
Definition: STTx.h:198
SerializedTypeID getSType() const override
Definition: STTx.cpp:142
std::string getFullText() const override
Definition: STTx.cpp:148
STBase * copy(std::size_t n, void *buf) const override
Definition: STTx.cpp:129
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:377
Slice slice() const noexcept
Definition: Serializer.h:67
Blob const & peekData() const
Definition: Serializer.h:203
Blob getData() const
Definition: Serializer.h:208
int getDataLength() const
Definition: Serializer.h:219
static TxFormats const & getInstance()
Definition: TxFormats.cpp:70
Add a memo to a JTx.
Definition: memo.h:35
Set the regular signature on a JTx.
Definition: sig.h:35
T empty(T... args)
@ objectValue
object value (collection of name/value pairs).
Definition: json_value.h:46
Json::Value signers(Account const &account, std::uint32_t quorum, std::vector< signer > const &v)
Definition: multisign.cpp:34
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:114
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Definition: STTx.cpp:637
bool isXRP(AccountID const &c)
Definition: AccountID.h:91
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
static bool isAccountFieldOkay(STObject const &st)
Definition: STTx.cpp:569
void finishMultiSigningData(AccountID const &signingID, Serializer &s)
Definition: Sign.h:86
TxType
Transaction type identifiers.
Definition: TxFormats.h:57
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
Definition: STTx.cpp:646
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.
Definition: PublicKey.cpp:288
base_uint< 256 > uint256
Definition: base_uint.h:558
static bool isMemoOkay(STObject const &st, std::string &reason)
Definition: STTx.cpp:477
SerializedTypeID
Definition: SField.h:107
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:42
std::size_t constexpr txMinSizeBytes
Protocol specific constants.
Definition: Protocol.h:42
static auto getTxFormat(TxType type)
Definition: STTx.cpp:73
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &message)
Generate a signature for a message.
Definition: SecretKey.cpp:256
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:223
static bool invalidMPTAmountInTx(STObject const &tx)
Definition: STTx.cpp:582
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
@ 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:185
bool passesLocalChecks(STObject const &st, std::string &)
Definition: STTx.cpp:610
@ soeMPTNone
Definition: SOTemplate.h:44
@ soeMPTSupported
Definition: SOTemplate.h:44
std::size_t constexpr txMaxSizeBytes
Largest legal byte size of a transaction.
Definition: Protocol.h:45
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
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:37
STL namespace.
T ref(T... args)
Note, should be treated as flags that can be | and &.
Definition: STBase.h:38
Set the sequence number on a JTx.
Definition: seq.h:34
A signer in a SignerList.
Definition: multisign.h:38
T to_string(T... args)