xrpld
Loading...
Searching...
No Matches
STValidation.h
1#pragma once
2
3#include <xrpl/basics/Blob.h>
4#include <xrpl/basics/CountedObject.h>
5#include <xrpl/basics/Log.h>
6#include <xrpl/basics/Slice.h>
7#include <xrpl/basics/base_uint.h>
8#include <xrpl/basics/chrono.h>
9#include <xrpl/basics/contract.h>
10#include <xrpl/beast/utility/instrumentation.h>
11#include <xrpl/protocol/KeyType.h>
12#include <xrpl/protocol/PublicKey.h>
13#include <xrpl/protocol/SField.h>
14#include <xrpl/protocol/SOTemplate.h>
15#include <xrpl/protocol/STBase.h>
16#include <xrpl/protocol/STObject.h>
17#include <xrpl/protocol/SecretKey.h>
18#include <xrpl/protocol/Serializer.h>
19#include <xrpl/protocol/UintTypes.h>
20#include <xrpl/protocol/tokens.h>
21
22#include <cstddef>
23#include <cstdint>
24#include <optional>
25#include <sstream>
26#include <stdexcept>
27#include <string>
28
29namespace xrpl {
30
31// Validation flags
32
33// This is a full (as opposed to a partial) validation
34constexpr std::uint32_t kVfFullValidation = 0x00000001;
35
36// The signature is fully canonical
37constexpr std::uint32_t kVfFullyCanonicalSig = 0x80000000;
38
39class STValidation final : public STObject, public CountedObject<STValidation>
40{
41 bool trusted_ = false;
42
43 // Determines the validity of the signature in this validation; unseated
44 // optional if we haven't yet checked it, a boolean otherwise.
46
47 // The public key associated with the key used to sign this validation
49
50 // The ID of the validator that issued this validation. For validators
51 // that use manifests this will be derived from the master public key.
53
55
56public:
72
87 template <class LookupNodeID>
88 STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, DeserializeOptions options);
89
99 template <typename F>
101 NetClock::time_point signTime,
102 PublicKey const& pk,
103 SecretKey const& sk,
104 NodeID const& nodeID,
105 F&& f);
106
107 // Hash of the validated ledger
108 [[nodiscard]] uint256
109 getLedgerHash() const;
110
111 // Hash of consensus transaction set used to generate ledger
112 [[nodiscard]] uint256
113 getConsensusHash() const;
114
115 [[nodiscard]] NetClock::time_point
116 getSignTime() const;
117
118 [[nodiscard]] NetClock::time_point
119 getSeenTime() const noexcept;
120
121 [[nodiscard]] PublicKey const&
122 getSignerPublic() const noexcept;
123
124 [[nodiscard]] NodeID const&
125 getNodeID() const noexcept;
126
127 [[nodiscard]] bool
128 isValid() const noexcept;
129
130 [[nodiscard]] bool
131 isFull() const noexcept;
132
133 [[nodiscard]] bool
134 isTrusted() const noexcept;
135
136 [[nodiscard]] uint256
137 getSigningHash() const;
138
139 void
140 setTrusted();
141
142 void
143 setUntrusted();
144
145 void
146 setSeen(NetClock::time_point s);
147
148 [[nodiscard]] Blob
149 getSerialized() const;
150
151 [[nodiscard]] Blob
152 getSignature() const;
153
154 [[nodiscard]] std::string
155 render() const
156 {
158 ss << "validation: " << " ledger_hash: " << getLedgerHash()
159 << " consensus_hash: " << getConsensusHash()
160 << " sign_time: " << to_string(getSignTime())
161 << " seen_time: " << to_string(getSeenTime())
162 << " signer_public_key: " << getSignerPublic() << " node_id: " << getNodeID()
163 << " is_valid: " << isValid() << " is_full: " << isFull()
164 << " is_trusted: " << isTrusted() << " signing_hash: " << getSigningHash()
165 << " base58: " << toBase58(TokenType::NodePublic, getSignerPublic());
166 return ss.str();
167 }
168
169private:
170 static SOTemplate const&
172
173 STBase*
174 copy(std::size_t n, void* buf) const override;
175 STBase*
176 move(std::size_t n, void* buf) override;
177
178 friend class detail::STVar;
179};
180
181template <class LookupNodeID>
182STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, DeserializeOptions options)
183 : STObject(validationFormat(), sit, sfValidation, options.requireCanonicalOrder)
184 , signingPubKey_([this]() {
185 auto const spk = getFieldVL(sfSigningPubKey);
186
188 Throw<std::runtime_error>("Invalid public key in validation");
189
190 return PublicKey{makeSlice(spk)};
191 }())
192 , nodeID_(lookupNodeID(signingPubKey_))
193{
194 if (options.checkSignature && !isValid())
195 {
196 JLOG(debugLog().error()) << "Invalid signature in validation: "
198 Throw<std::runtime_error>("Invalid signature in validation");
199 }
200
201 XRPL_ASSERT(nodeID_.isNonZero(), "xrpl::STValidation::STValidation(SerialIter) : nonzero node");
202}
203
213template <typename F>
215 NetClock::time_point signTime,
216 PublicKey const& pk,
217 SecretKey const& sk,
218 NodeID const& nodeID,
219 F&& f)
220 : STObject(validationFormat(), sfValidation)
221 , signingPubKey_(pk)
222 , nodeID_(nodeID)
223 , seenTime_(signTime)
224{
225 XRPL_ASSERT(
226 nodeID_.isNonZero(),
227 "xrpl::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
228 "node");
229
230 // First, set our own public key:
232 logicError("We can only use secp256k1 keys for signing validations");
233
234 setFieldVL(sfSigningPubKey, pk.slice());
235 setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
236
237 // Perform additional initialization
238 f(*this);
239
240 // Finally, sign the validation and mark it as trusted:
242 setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
243 setTrusted();
244
245 // Check to ensure that all required fields are present.
246 for (auto const& e : validationFormat())
247 {
248 if (e.style() == SoeRequired && !isFieldPresent(e.sField()))
249 logicError("Required field '" + e.sField().getName() + "' missing from validation.");
250 }
251
252 // We just signed this, so it should be valid.
253 valid_ = true;
254}
255
256inline PublicKey const&
258{
259 return signingPubKey_;
260}
261
262inline NodeID const&
264{
265 return nodeID_;
266}
267
268inline bool
270{
271 return trusted_;
272}
273
274inline void
276{
277 trusted_ = true;
278}
279
280inline void
282{
283 trusted_ = false;
284}
285
286inline void
291
292} // namespace xrpl
std::chrono::time_point< NetClock > time_point
Definition chrono.h:48
A public key.
Definition PublicKey.h:53
Slice slice() const noexcept
Definition PublicKey.h:115
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:105
A type which can be exported to a well known binary format.
Definition STBase.h:129
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:649
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:791
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:743
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:464
STObject(STObject const &)=default
bool setFlag(std::uint32_t)
Definition STObject.cpp:487
NetClock::time_point getSignTime() const
static SOTemplate const & validationFormat()
STBase * move(std::size_t n, void *buf) override
Blob getSignature() const
NetClock::time_point getSeenTime() const noexcept
std::optional< bool > valid_
void setSeen(NetClock::time_point s)
uint256 getConsensusHash() const
STBase * copy(std::size_t n, void *buf) const override
NodeID const nodeID_
std::string render() const
NodeID const & getNodeID() const noexcept
bool isValid() const noexcept
bool isFull() const noexcept
uint256 getLedgerHash() const
PublicKey const signingPubKey_
PublicKey const & getSignerPublic() const noexcept
uint256 getSigningHash() const
Blob getSerialized() const
STValidation(SerialIter &sit, LookupNodeID &&lookupNodeID, DeserializeOptions options)
Construct a STValidation from a peer from serialized data.
bool isTrusted() const noexcept
NetClock::time_point seenTime_
A secret key.
Definition SecretKey.h:24
STL namespace.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:399
@ SoeRequired
Definition SOTemplate.h:22
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
std::string to_string(BaseUInt< Bits, Tag > const &a)
Definition base_uint.h:651
void logicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Slice makeSlice(std::array< T, N > const &a)
Definition Slice.h:228
json::Value getJson(LedgerFill const &fill)
Return a new json::Value representing the ledger with given options.
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
constexpr std::uint32_t kVfFullValidation
constexpr std::uint32_t kVfFullyCanonicalSig
std::vector< unsigned char > Blob
Storage for linear binary data.
Definition Blob.h:11
BaseUInt< 256 > uint256
Definition base_uint.h:580
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
Definition contract.h:52
BaseUInt< 160, detail::NodeIDTag > NodeID
NodeID is a 160-bit hash representing one node.
Definition UintTypes.h:47
T str(T... args)
Options controlling deserialization of a STValidation.
bool checkSignature
Whether to verify the data was signed properly.
bool requireCanonicalOrder
Whether to require the fields to be in canonical order.
T time_since_epoch(T... args)