20 #include <ripple/basics/Log.h>
21 #include <ripple/basics/StringUtilities.h>
22 #include <ripple/basics/contract.h>
23 #include <ripple/basics/safe_cast.h>
24 #include <ripple/json/to_string.h>
25 #include <ripple/protocol/Feature.h>
26 #include <ripple/protocol/HashPrefix.h>
27 #include <ripple/protocol/Protocol.h>
28 #include <ripple/protocol/PublicKey.h>
29 #include <ripple/protocol/STAccount.h>
30 #include <ripple/protocol/STArray.h>
31 #include <ripple/protocol/STTx.h>
32 #include <ripple/protocol/Sign.h>
33 #include <ripple/protocol/TxFlags.h>
34 #include <ripple/protocol/UintTypes.h>
35 #include <ripple/protocol/jss.h>
36 #include <boost/format.hpp>
50 if (format ==
nullptr)
52 Throw<std::runtime_error>(
53 "Invalid transaction type " +
72 Throw<std::runtime_error>(
"Transaction length invalid");
75 Throw<std::runtime_error>(
"Transaction contains an object terminator");
88 set(format->getSOTemplate());
96 LogicError(
"Transaction type was mutated during assembly");
110 return emplace(n, buf, std::move(*
this));
117 return STI_TRANSACTION;
131 boost::container::flat_set<AccountID>
134 boost::container::flat_set<AccountID> list;
136 for (
auto const& it : *
this)
138 if (
auto sacc =
dynamic_cast<STAccount const*
>(&it))
140 assert(!sacc->isDefault());
141 if (!sacc->isDefault())
142 list.insert(sacc->value());
144 else if (
auto samt =
dynamic_cast<STAmount const*
>(&it))
146 auto const& issuer = samt->getIssuer();
212 Rules const& rules)
const
220 return signingPubKey.
empty()
227 return Unexpected(
"Internal signature check failure.");
252 ret[jss::tx] = dataBin;
271 "INSERT OR REPLACE INTO Transactions "
272 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, "
296 static boost::format bfTrans(
297 "('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
301 assert(format !=
nullptr);
316 return Unexpected(
"Cannot both single- and multi-sign.");
318 bool validSig =
false;
343 if (validSig ==
false)
352 Rules const& rules)
const
362 return Unexpected(
"Cannot both single- and multi-sign.");
369 return Unexpected(
"Invalid Signers array size.");
386 for (
auto const& signer : signers)
388 auto const accountID = signer.getAccountID(
sfAccount);
391 if (accountID == txnAccountID)
395 if (lastAccountID == accountID)
396 return Unexpected(
"Duplicate Signers not allowed.");
399 if (lastAccountID > accountID)
403 lastAccountID = accountID;
406 bool validSig =
false;
457 reason =
"The memo exceeds the maximum allowed size.";
461 for (
auto const& memo : memos)
463 auto memoObj =
dynamic_cast<STObject const*
>(&memo);
465 if (!memoObj || (memoObj->getFName() !=
sfMemo))
467 reason =
"A memo array may contain only Memo objects.";
471 for (
auto const& memoElement : *memoObj)
473 auto const& name = memoElement.getFName();
479 "A memo may contain only MemoType, MemoData or "
480 "MemoFormat fields.";
485 auto optData =
strUnHex(memoElement.getText());
490 "The MemoType, MemoData and MemoFormat fields may "
491 "only contain hex-encoded data.";
506 "-._~:/?#[]@!$&'()*+,;=%"
507 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
508 "abcdefghijklmnopqrstuvwxyz");
510 for (
char c : symbols)
515 for (
auto c : *optData)
517 if (!allowedSymbols[c])
520 "The MemoType and MemoFormat fields may only "
521 "contain characters that are allowed in URLs "
536 for (
int i = 0; i < st.
getCount(); ++i)
539 if (t && t->isDefault())
554 reason =
"An account field is invalid.";
560 reason =
"Cannot submit pseudo transactions.";
572 return std::make_shared<STTx const>(
std::ref(sit));
581 auto tt = safe_cast<TxType>(*t);
static auto getTxFormat(TxType type)
static bool isAccountFieldOkay(STObject const &st)
const STArray & getFieldArray(SField const &field) const
void applyTemplate(const SOTemplate &type)
std::vector< unsigned char > Blob
Storage for linear binary data.
std::string getMetaSQL(std::uint32_t inLedger, std::string const &escapedMetaData) const
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)
void setFieldU16(SField const &field, std::uint16_t)
const STBase * peekAtPIndex(int offset) const
const SF_UINT32 sfSequence
constexpr std::size_t txMinSizeBytes
Protocol specific constants.
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical) noexcept
Verify a signature on a message.
const SF_VL sfSigningPubKey
Unexpected(E(&)[N]) -> Unexpected< E const * >
@ ttFEE
This system-generated transaction type is used to update the network's fee settings.
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
constexpr std::uint32_t tfFullyCanonicalSig
Transaction flags.
Serializer getSerializer() const
static constexpr SeqProxy sequence(std::uint32_t v)
Factory function to return a sequence-based SeqProxy.
TxType
Transaction type identifiers.
uint256 getSigningHash() const
SeqProxy getSeqProxy() const
const SF_UINT32 sfTicketSequence
static std::string const & getMetaSQLInsertReplaceHeader()
void setFieldVL(SField const &field, Blob const &)
Blob getFieldVL(SField const &field) const
@ ttAMENDMENT
This system-generated transaction type is used to update the status of the various amendments.
void finishMultiSigningData(AccountID const &signingID, Serializer &s)
std::string getFullText() const override
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
int getDataLength() const
const SF_UINT16 sfTransactionType
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
static Blob getSigningData(STTx const &that)
@ ttUNL_MODIFY
This system-generated transaction type is used to update the network's negative UNL.
@ objectValue
object value (collection of name/value pairs).
bool passesLocalChecks(STObject const &st, std::string &reason)
static STBase * emplace(std::size_t n, void *buf, T &&val)
AccountID getAccountID(SField const &field) const
std::string getFullText() const override
constexpr std::enable_if_t< std::is_same_v< typename Dest::unit_type, typename Src::unit_type > &&std::is_integral_v< typename Dest::value_type > &&std::is_integral_v< typename Src::value_type >, Dest > safe_cast(Src s) noexcept
Serializer startMultiSigningData(STObject const &obj)
Break the multi-signing hash computation into 2 parts for optimization.
static bool isMemoOkay(STObject const &st, std::string &reason)
Slice slice() const noexcept
std::uint32_t getFlags() const
bool isXRP(AccountID const &c)
@ transactionID
transaction plus signature to give transaction ID
static std::size_t maxMultiSigners(Rules const *rules=0)
void addWithoutSigningFields(Serializer &s) const
constexpr std::size_t txMaxSizeBytes
Largest legal byte size of a transaction.
void sign(PublicKey const &publicKey, SecretKey const &secretKey)
std::uint16_t getFieldU16(SField const &field) const
Json::Value getJson(JsonOptions options) const override
uint256 getTransactionID() const
void add(Serializer &s) const override
const SF_VL sfTxnSignature
Expected< void, std::string > checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
std::shared_ptr< STTx const > sterilize(STTx const &stx)
Sterilize a transaction.
Note, should be treated as flags that can be | and &.
uint256 getSigningHash(HashPrefix prefix) const
int getBytesLeft() const noexcept
Expected< void, std::string > checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
A type which can be exported to a well known binary format.
Blob getSignature() const
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
bool isFieldPresent(SField const &field) const
Blob const & peekData() const
boost::container::flat_set< AccountID > getMentionedAccounts() const
A type that represents either a sequence value or a ticket value.
Rules controlling protocol behavior.
static const std::size_t minMultiSigners
STBase * copy(std::size_t n, void *buf) const override
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
const SF_ACCOUNT sfAccount
int add32(std::uint32_t i)
std::string strHex(FwdIt begin, FwdIt end)
@ txSign
inner transaction to sign
T::value_type operator[](TypedField< T > const &f) const
Get the value of a field.
std::uint32_t getFieldU32(SField const &field) const
Json::Value getJson(JsonOptions options) const override
std::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
Expected< void, std::string > checkMultiSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const &rules) const
void set(const SOTemplate &)
STBase * move(std::size_t n, void *buf) override
RequireFullyCanonicalSig
Check the signature.
const SField sfTransaction
std::string sqlBlobLiteral(Blob const &blob)
Format arbitrary binary data as an SQLite "blob literal".
SerializedTypeID getSType() const override
uint256 getHash(HashPrefix prefix) const