20 #include <ripple/protocol/STTx.h>
21 #include <ripple/basics/contract.h>
22 #include <ripple/basics/Log.h>
23 #include <ripple/basics/safe_cast.h>
24 #include <ripple/basics/StringUtilities.h>
25 #include <ripple/protocol/Feature.h>
26 #include <ripple/protocol/HashPrefix.h>
27 #include <ripple/protocol/jss.h>
28 #include <ripple/protocol/Protocol.h>
29 #include <ripple/protocol/PublicKey.h>
30 #include <ripple/protocol/Sign.h>
31 #include <ripple/protocol/STAccount.h>
32 #include <ripple/protocol/STArray.h>
33 #include <ripple/protocol/TxFlags.h>
34 #include <ripple/protocol/UintTypes.h>
35 #include <ripple/json/to_string.h>
36 #include <boost/format.hpp>
49 if (format ==
nullptr)
51 Throw<std::runtime_error> (
52 "Invalid transaction type " +
64 applyTemplate (
getTxFormat (tx_type_)->getSOTemplate());
71 int length = sit.getBytesLeft ();
74 Throw<std::runtime_error> (
"Transaction length invalid");
77 Throw<std::runtime_error> (
"Transaction contains an object terminator");
81 applyTemplate (
getTxFormat (tx_type_)->getSOTemplate());
92 set (format->getSOTemplate());
100 LogicError (
"Transaction type was mutated during assembly");
116 boost::container::flat_set<AccountID>
119 boost::container::flat_set<AccountID> list;
121 for (
auto const& it : *
this)
123 if (
auto sacc =
dynamic_cast<STAccount const*
> (&it))
125 assert(! sacc->isDefault());
126 if (! sacc->isDefault())
127 list.insert(sacc->value());
129 else if (
auto samt =
dynamic_cast<STAmount const*
> (&it))
131 auto const& issuer = samt->getIssuer ();
132 if (!
isXRP (issuer))
191 ret = signingPubKey.
empty () ?
197 ret = {
false,
"Internal signature check failure."};
225 static std::string const sql =
"INSERT OR REPLACE INTO Transactions "
226 "(TransID, TransType, FromAcct, FromSeq, LedgerSeq, Status, RawTxn, TxnMeta)"
245 static boost::format bfTrans (
"('%s', '%s', '%s', '%d', '%d', '%c', %s, %s)");
249 assert (format !=
nullptr);
251 return str (boost::format (bfTrans)
254 %
getSequence () % inLedger % status % rTxn % escapedMetaData);
264 return {
false,
"Cannot both single- and multi-sign."};
266 bool validSig =
false;
292 if (validSig ==
false)
293 return {
false,
"Invalid signature."};
304 return {
false,
"Empty SigningPubKey."};
309 return {
false,
"Cannot both single- and multi-sign."};
315 return {
false,
"Invalid Signers array size."};
333 for (
auto const& signer : signers)
335 auto const accountID = signer.getAccountID (
sfAccount);
338 if (accountID == txnAccountID)
339 return {
false,
"Invalid multisigner."};
342 if (lastAccountID == accountID)
343 return {
false,
"Duplicate Signers not allowed."};
346 if (lastAccountID > accountID)
347 return {
false,
"Unsorted Signers array."};
350 lastAccountID = accountID;
353 bool validSig =
false;
363 Blob const signature =
379 return {
false,
std::string(
"Invalid signature on account ") +
406 reason =
"The memo exceeds the maximum allowed size.";
410 for (
auto const& memo : memos)
412 auto memoObj =
dynamic_cast <STObject const*
> (&memo);
414 if (!memoObj || (memoObj->getFName() !=
sfMemo))
416 reason =
"A memo array may contain only Memo objects.";
420 for (
auto const& memoElement : *memoObj)
422 auto const& name = memoElement.getFName();
428 reason =
"A memo may contain only MemoType, MemoData or "
429 "MemoFormat fields.";
434 auto optData =
strUnHex (memoElement.getText ());
438 reason =
"The MemoType, MemoData and MemoFormat fields may "
439 "only contain hex-encoded data.";
456 "-._~:/?#[]@!$&'()*+,;=%"
457 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
458 "abcdefghijklmnopqrstuvwxyz");
460 for(
char c : symbols)
465 for (
auto c : *optData)
467 if (!allowedSymbols[c])
469 reason =
"The MemoType and MemoFormat fields may only "
470 "contain characters that are allowed in URLs "
486 for (
int i = 0; i < st.
getCount(); ++i)
489 if (t && t->isDefault ())
503 reason =
"An account field is invalid.";
509 reason =
"Cannot submit pseudo transactions.";
521 return std::make_shared<STTx const>(
std::ref(sit));
530 auto tt = safe_cast<TxType>(*t);
static auto getTxFormat(TxType type)
static bool isAccountFieldOkay(STObject const &st)
std::pair< bool, std::string > checkMultiSign(RequireFullyCanonicalSig requireCanonicalSig) const
const STArray & getFieldArray(SField const &field) const
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)
std::pair< bool, std::string > checkSign(RequireFullyCanonicalSig requireCanonicalSig) const
void setFieldU16(SField const &field, std::uint16_t)
boost::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
const SField sfSigners(access, STI_ARRAY, 3, "Signers", SField::sMD_Default, SField::notSigning)
const SF_Blob sfMemoType(access, STI_VL, 12, "MemoType")
const SF_Blob sfSigningPubKey(access, STI_VL, 3, "SigningPubKey")
constexpr std::size_t txMinSizeBytes
Protocol specific constants, types, and data.
const SF_Account sfAccount(access, STI_ACCOUNT, 1, "Account")
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Serializer getSerializer() const
uint256 getSigningHash() const
boost::optional< Blob > strUnHex(std::size_t strSize, Iterator begin, Iterator end)
static std::string const & getMetaSQLInsertReplaceHeader()
static std::string sqlEscape(std::string const &strSrc)
std::string to_string(ListDisposition disposition)
void setFieldVL(SField const &field, Blob const &)
Blob getFieldVL(SField const &field) const
const STBase * peekAtPIndex(int offset) const
void finishMultiSigningData(AccountID const &signingID, Serializer &s)
virtual std::string getFullText() const override
const SF_Blob sfMemoData(access, STI_VL, 13, "MemoData")
bool verify(PublicKey const &publicKey, Slice const &m, Slice const &sig, bool mustBeFullyCanonical)
Verify a signature on a message.
int getDataLength() const
bool isPseudoTx(STObject const &tx)
Check whether a transaction is a pseudo-transaction.
static Blob getSigningData(STTx const &that)
bool passesLocalChecks(STObject const &st, std::string &reason)
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.
const SField sfTransaction(access, STI_TRANSACTION, 257, "Transaction")
static bool isMemoOkay(STObject const &st, std::string &reason)
const std::uint32_t tfFullyCanonicalSig
bool set(T &target, std::string const &name, Section const §ion)
Set a value from a configuration Section If the named value is not found or doesn't parse as a T,...
const SF_Blob sfTxnSignature(access, STI_VL, 4, "TxnSignature", SField::sMD_Default, SField::notSigning)
const SF_U16 sfTransactionType(access, STI_UINT16, 2, "TransactionType")
Slice slice() const noexcept
UInt size() const
Number of values in array or object.
std::uint32_t getFlags() const
bool isXRP(AccountID const &c)
@ transactionID
transaction plus signature to give transaction ID
std::pair< bool, std::string > checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const
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
std::uint32_t getSequence() const
uint256 getTransactionID() const
const SField sfMemo(access, STI_OBJECT, 10, "Memo")
TxType
Transaction type identifiers.
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.
static const std::size_t maxMultiSigners
uint256 getSigningHash(HashPrefix prefix) const
virtual void add(Serializer &s) const override
Buffer sign(PublicKey const &pk, SecretKey const &sk, Slice const &m)
Generate a signature for a message.
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
const SField sfMemos(access, STI_ARRAY, 9, "Memos")
static const std::size_t minMultiSigners
std::vector< unsigned char > Blob
Storage for linear binary data.
std::string strHex(FwdIt begin, FwdIt end)
@ txSign
inner transaction to sign
virtual Json::Value getJson(JsonOptions options) const override
void set(const SOTemplate &)
RequireFullyCanonicalSig
Check the signature.
const SF_Blob sfMemoFormat(access, STI_VL, 14, "MemoFormat")
uint256 getHash(HashPrefix prefix) const