Skip to content

Commit 587d4ac

Browse files
ximinezvvysokikh1
authored andcommitted
refactor: Add support for extra transaction signature validation (#5851)
- Restructures `STTx` signature checking code to be able to handle a `sigObject`, which may be the full transaction, or may be an object field containing a separate signature. Either way, the `sigObject` can be a single- or multi-sign signature. - This is distinct from 550f90a (#5594), which changed the check in Transactor, which validates whether a given account is allowed to sign for the given transaction. This cryptographically checks the signature validity.
1 parent 13b169f commit 587d4ac

File tree

22 files changed

+502
-121
lines changed

22 files changed

+502
-121
lines changed

include/xrpl/protocol/STObject.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,9 @@ class STObject : public STBase, public CountedObject<STObject>
244244
getFieldPathSet(SField const& field) const;
245245
STVector256 const&
246246
getFieldV256(SField const& field) const;
247+
// If not found, returns an object constructed with the given field
248+
STObject
249+
getFieldObject(SField const& field) const;
247250
STArray const&
248251
getFieldArray(SField const& field) const;
249252
STCurrency const&
@@ -390,6 +393,8 @@ class STObject : public STBase, public CountedObject<STObject>
390393
setFieldV256(SField const& field, STVector256 const& v);
391394
void
392395
setFieldArray(SField const& field, STArray const& v);
396+
void
397+
setFieldObject(SField const& field, STObject const& v);
393398

394399
template <class Tag>
395400
void

include/xrpl/protocol/STTx.h

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,14 @@ class STTx final : public STObject, public CountedObject<STTx>
8787
getFullText() const override;
8888

8989
// Outer transaction functions / signature functions.
90+
static Blob
91+
getSignature(STObject const& sigObject);
92+
9093
Blob
91-
getSignature() const;
94+
getSignature() const
95+
{
96+
return getSignature(*this);
97+
}
9298

9399
uint256
94100
getSigningHash() const;
@@ -119,13 +125,20 @@ class STTx final : public STObject, public CountedObject<STTx>
119125
getJson(JsonOptions options, bool binary) const;
120126

121127
void
122-
sign(PublicKey const& publicKey, SecretKey const& secretKey);
128+
sign(
129+
PublicKey const& publicKey,
130+
SecretKey const& secretKey,
131+
std::optional<std::reference_wrapper<SField const>> signatureTarget =
132+
{});
133+
134+
enum class RequireFullyCanonicalSig : bool { no, yes };
123135

124136
/** Check the signature.
137+
@param requireCanonicalSig If `true`, check that the signature is fully
138+
canonical. If `false`, only check that the signature is valid.
139+
@param rules The current ledger rules.
125140
@return `true` if valid signature. If invalid, the error message string.
126141
*/
127-
enum class RequireFullyCanonicalSig : bool { no, yes };
128-
129142
Expected<void, std::string>
130143
checkSign(RequireFullyCanonicalSig requireCanonicalSig, Rules const& rules)
131144
const;
@@ -150,17 +163,34 @@ class STTx final : public STObject, public CountedObject<STTx>
150163
char status,
151164
std::string const& escapedMetaData) const;
152165

153-
std::vector<uint256>
166+
std::vector<uint256> const&
154167
getBatchTransactionIDs() const;
155168

156169
private:
170+
/** Check the signature.
171+
@param requireCanonicalSig If `true`, check that the signature is fully
172+
canonical. If `false`, only check that the signature is valid.
173+
@param rules The current ledger rules.
174+
@param sigObject Reference to object that contains the signature fields.
175+
Will be *this more often than not.
176+
@return `true` if valid signature. If invalid, the error message string.
177+
*/
157178
Expected<void, std::string>
158-
checkSingleSign(RequireFullyCanonicalSig requireCanonicalSig) const;
179+
checkSign(
180+
RequireFullyCanonicalSig requireCanonicalSig,
181+
Rules const& rules,
182+
STObject const& sigObject) const;
183+
184+
Expected<void, std::string>
185+
checkSingleSign(
186+
RequireFullyCanonicalSig requireCanonicalSig,
187+
STObject const& sigObject) const;
159188

160189
Expected<void, std::string>
161190
checkMultiSign(
162191
RequireFullyCanonicalSig requireCanonicalSig,
163-
Rules const& rules) const;
192+
Rules const& rules,
193+
STObject const& sigObject) const;
164194

165195
Expected<void, std::string>
166196
checkBatchSingleSign(
@@ -179,7 +209,7 @@ class STTx final : public STObject, public CountedObject<STTx>
179209
move(std::size_t n, void* buf) override;
180210

181211
friend class detail::STVar;
182-
mutable std::vector<uint256> batch_txn_ids_;
212+
mutable std::vector<uint256> batchTxnIds_;
183213
};
184214

185215
bool

include/xrpl/protocol/jss.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -569,6 +569,7 @@ JSS(settle_delay); // out: AccountChannels
569569
JSS(severity); // in: LogLevel
570570
JSS(shares); // out: VaultInfo
571571
JSS(signature); // out: NetworkOPs, ChannelAuthorize
572+
JSS(signature_target); // in: TransactionSign
572573
JSS(signature_verified); // out: ChannelVerify
573574
JSS(signing_key); // out: NetworkOPs
574575
JSS(signing_keys); // out: ValidatorList

src/libxrpl/protocol/STObject.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -688,6 +688,16 @@ STObject::getFieldV256(SField const& field) const
688688
return getFieldByConstRef<STVector256>(field, empty);
689689
}
690690

691+
STObject
692+
STObject::getFieldObject(SField const& field) const
693+
{
694+
STObject const empty{field};
695+
auto ret = getFieldByConstRef<STObject>(field, empty);
696+
if (ret != empty)
697+
ret.applyTemplateFromSField(field);
698+
return ret;
699+
}
700+
691701
STArray const&
692702
STObject::getFieldArray(SField const& field) const
693703
{
@@ -833,6 +843,12 @@ STObject::setFieldArray(SField const& field, STArray const& v)
833843
setFieldUsingAssignment(field, v);
834844
}
835845

846+
void
847+
STObject::setFieldObject(SField const& field, STObject const& v)
848+
{
849+
setFieldUsingAssignment(field, v);
850+
}
851+
836852
Json::Value
837853
STObject::getJson(JsonOptions options) const
838854
{

0 commit comments

Comments
 (0)