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