rippled
Loading...
Searching...
No Matches
STValidation.h
1#ifndef XRPL_PROTOCOL_STVALIDATION_H_INCLUDED
2#define XRPL_PROTOCOL_STVALIDATION_H_INCLUDED
3
4#include <xrpl/basics/Log.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/protocol/PublicKey.h>
7#include <xrpl/protocol/STObject.h>
8#include <xrpl/protocol/SecretKey.h>
9#include <xrpl/protocol/Units.h>
10
11#include <cstdint>
12#include <optional>
13#include <sstream>
14
15namespace ripple {
16
17// Validation flags
18
19// This is a full (as opposed to a partial) validation
20constexpr std::uint32_t vfFullValidation = 0x00000001;
21
22// The signature is fully canonical
23constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
24
25class STValidation final : public STObject, public CountedObject<STValidation>
26{
27 bool mTrusted = false;
28
29 // Determines the validity of the signature in this validation; unseated
30 // optional if we haven't yet checked it, a boolean otherwise.
32
33 // The public key associated with the key used to sign this validation
35
36 // The ID of the validator that issued this validation. For validators
37 // that use manifests this will be derived from the master public key.
39
41
42public:
56 template <class LookupNodeID>
58 SerialIter& sit,
59 LookupNodeID&& lookupNodeID,
60 bool checkSignature);
61
70 template <typename F>
72 NetClock::time_point signTime,
73 PublicKey const& pk,
74 SecretKey const& sk,
75 NodeID const& nodeID,
76 F&& f);
77
78 // Hash of the validated ledger
80 getLedgerHash() const;
81
82 // Hash of consensus transaction set used to generate ledger
84 getConsensusHash() const;
85
87 getSignTime() const;
88
90 getSeenTime() const noexcept;
91
92 PublicKey const&
93 getSignerPublic() const noexcept;
94
95 NodeID const&
96 getNodeID() const noexcept;
97
98 bool
99 isValid() const noexcept;
100
101 bool
102 isFull() const noexcept;
103
104 bool
105 isTrusted() const noexcept;
106
107 uint256
108 getSigningHash() const;
109
110 void
111 setTrusted();
112
113 void
114 setUntrusted();
115
116 void
117 setSeen(NetClock::time_point s);
118
119 Blob
120 getSerialized() const;
121
122 Blob
123 getSignature() const;
124
125 std::string
126 render() const
127 {
129 ss << "validation: " << " ledger_hash: " << getLedgerHash()
130 << " consensus_hash: " << getConsensusHash()
131 << " sign_time: " << to_string(getSignTime())
132 << " seen_time: " << to_string(getSeenTime())
133 << " signer_public_key: " << getSignerPublic()
134 << " node_id: " << getNodeID() << " is_valid: " << isValid()
135 << " is_full: " << isFull() << " is_trusted: " << isTrusted()
136 << " signing_hash: " << getSigningHash()
137 << " base58: " << toBase58(TokenType::NodePublic, getSignerPublic());
138 return ss.str();
139 }
140
141private:
142 static SOTemplate const&
144
145 STBase*
146 copy(std::size_t n, void* buf) const override;
147 STBase*
148 move(std::size_t n, void* buf) override;
149
150 friend class detail::STVar;
151};
152
153template <class LookupNodeID>
155 SerialIter& sit,
156 LookupNodeID&& lookupNodeID,
157 bool checkSignature)
158 : STObject(validationFormat(), sit, sfValidation)
159 , signingPubKey_([this]() {
160 auto const spk = getFieldVL(sfSigningPubKey);
161
163 Throw<std::runtime_error>("Invalid public key in validation");
164
165 return PublicKey{makeSlice(spk)};
166 }())
167 , nodeID_(lookupNodeID(signingPubKey_))
168{
169 if (checkSignature && !isValid())
170 {
171 JLOG(debugLog().error()) << "Invalid signature in validation: "
173 Throw<std::runtime_error>("Invalid signature in validation");
174 }
175
176 XRPL_ASSERT(
177 nodeID_.isNonZero(),
178 "ripple::STValidation::STValidation(SerialIter) : nonzero node");
179}
180
189template <typename F>
191 NetClock::time_point signTime,
192 PublicKey const& pk,
193 SecretKey const& sk,
194 NodeID const& nodeID,
195 F&& f)
196 : STObject(validationFormat(), sfValidation)
197 , signingPubKey_(pk)
198 , nodeID_(nodeID)
199 , seenTime_(signTime)
200{
201 XRPL_ASSERT(
203 "ripple::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
204 "node");
205
206 // First, set our own public key:
208 LogicError("We can only use secp256k1 keys for signing validations");
209
210 setFieldVL(sfSigningPubKey, pk.slice());
211 setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
212
213 // Perform additional initialization
214 f(*this);
215
216 // Finally, sign the validation and mark it as trusted:
218 setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
219 setTrusted();
220
221 // Check to ensure that all required fields are present.
222 for (auto const& e : validationFormat())
223 {
224 if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
226 "Required field '" + e.sField().getName() +
227 "' missing from validation.");
228 }
229
230 // We just signed this, so it should be valid.
231 valid_ = true;
232}
233
234inline PublicKey const&
236{
237 return signingPubKey_;
238}
239
240inline NodeID const&
242{
243 return nodeID_;
244}
245
246inline bool
248{
249 return mTrusted;
250}
251
252inline void
254{
255 mTrusted = true;
256}
257
258inline void
260{
261 mTrusted = false;
262}
263
264inline void
269
270} // namespace ripple
271
272#endif
Tracks the number of instances of an object.
A public key.
Definition PublicKey.h:43
Slice slice() const noexcept
Definition PublicKey.h:104
Defines the fields and their attributes within a STObject.
Definition SOTemplate.h:94
A type which can be exported to a well known binary format.
Definition STBase.h:116
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:644
bool setFlag(std::uint32_t)
Definition STObject.cpp:488
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:465
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:738
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:780
PublicKey const & getSignerPublic() const noexcept
uint256 getConsensusHash() const
std::string render() const
std::optional< bool > valid_
STValidation(SerialIter &sit, LookupNodeID &&lookupNodeID, bool checkSignature)
Construct a STValidation from a peer from serialized data.
Blob getSerialized() const
NetClock::time_point getSeenTime() const noexcept
void setSeen(NetClock::time_point s)
bool isTrusted() const noexcept
NodeID const nodeID_
PublicKey const signingPubKey_
static SOTemplate const & validationFormat()
NodeID const & getNodeID() const noexcept
bool isFull() const noexcept
NetClock::time_point seenTime_
STBase * copy(std::size_t n, void *buf) const override
uint256 getLedgerHash() const
bool isValid() const noexcept
uint256 getSigningHash() const
Blob getSignature() const
STBase * move(std::size_t n, void *buf) override
NetClock::time_point getSignTime() const
A secret key.
Definition SecretKey.h:19
bool isNonZero() const
Definition base_uint.h:526
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition AccountID.cpp:95
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
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:225
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:457
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
constexpr std::uint32_t vfFullyCanonicalSig
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:611
constexpr std::uint32_t vfFullValidation
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
@ soeREQUIRED
Definition SOTemplate.h:16
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
STL namespace.
T str(T... args)
T time_since_epoch(T... args)