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>
67 STValidation(NetClock::time_point signTime, PublicKey const& pk, SecretKey const& sk, NodeID const& nodeID, F&& f);
68
69 // Hash of the validated ledger
71 getLedgerHash() const;
72
73 // Hash of consensus transaction set used to generate ledger
75 getConsensusHash() const;
76
78 getSignTime() const;
79
81 getSeenTime() const noexcept;
82
83 PublicKey const&
84 getSignerPublic() const noexcept;
85
86 NodeID const&
87 getNodeID() const noexcept;
88
89 bool
90 isValid() const noexcept;
91
92 bool
93 isFull() const noexcept;
94
95 bool
96 isTrusted() const noexcept;
97
99 getSigningHash() const;
100
101 void
102 setTrusted();
103
104 void
105 setUntrusted();
106
107 void
108 setSeen(NetClock::time_point s);
109
110 Blob
111 getSerialized() const;
112
113 Blob
114 getSignature() const;
115
116 std::string
117 render() const
118 {
120 ss << "validation: " << " ledger_hash: " << getLedgerHash() << " consensus_hash: " << getConsensusHash()
121 << " sign_time: " << to_string(getSignTime()) << " seen_time: " << to_string(getSeenTime())
122 << " signer_public_key: " << getSignerPublic() << " node_id: " << getNodeID() << " is_valid: " << isValid()
123 << " is_full: " << isFull() << " is_trusted: " << isTrusted() << " signing_hash: " << getSigningHash()
124 << " base58: " << toBase58(TokenType::NodePublic, getSignerPublic());
125 return ss.str();
126 }
127
128private:
129 static SOTemplate const&
131
132 STBase*
133 copy(std::size_t n, void* buf) const override;
134 STBase*
135 move(std::size_t n, void* buf) override;
136
137 friend class detail::STVar;
138};
139
140template <class LookupNodeID>
141STValidation::STValidation(SerialIter& sit, LookupNodeID&& lookupNodeID, bool checkSignature)
142 : STObject(validationFormat(), sit, sfValidation)
143 , signingPubKey_([this]() {
144 auto const spk = getFieldVL(sfSigningPubKey);
145
147 Throw<std::runtime_error>("Invalid public key in validation");
148
149 return PublicKey{makeSlice(spk)};
150 }())
151 , nodeID_(lookupNodeID(signingPubKey_))
152{
153 if (checkSignature && !isValid())
154 {
155 JLOG(debugLog().error()) << "Invalid signature in validation: " << getJson(JsonOptions::none);
156 Throw<std::runtime_error>("Invalid signature in validation");
157 }
158
159 XRPL_ASSERT(nodeID_.isNonZero(), "xrpl::STValidation::STValidation(SerialIter) : nonzero node");
160}
161
170template <typename F>
172 NetClock::time_point signTime,
173 PublicKey const& pk,
174 SecretKey const& sk,
175 NodeID const& nodeID,
176 F&& f)
177 : STObject(validationFormat(), sfValidation), signingPubKey_(pk), nodeID_(nodeID), seenTime_(signTime)
178{
179 XRPL_ASSERT(
181 "xrpl::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
182 "node");
183
184 // First, set our own public key:
186 LogicError("We can only use secp256k1 keys for signing validations");
187
188 setFieldVL(sfSigningPubKey, pk.slice());
189 setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
190
191 // Perform additional initialization
192 f(*this);
193
194 // Finally, sign the validation and mark it as trusted:
196 setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
197 setTrusted();
198
199 // Check to ensure that all required fields are present.
200 for (auto const& e : validationFormat())
201 {
202 if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
203 LogicError("Required field '" + e.sField().getName() + "' missing from validation.");
204 }
205
206 // We just signed this, so it should be valid.
207 valid_ = true;
208}
209
210inline PublicKey const&
212{
213 return signingPubKey_;
214}
215
216inline NodeID const&
218{
219 return nodeID_;
220}
221
222inline bool
224{
225 return mTrusted;
226}
227
228inline void
230{
231 mTrusted = true;
232}
233
234inline void
236{
237 mTrusted = false;
238}
239
240inline void
245
246} // 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:88
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:624
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:760
void setFieldU32(SField const &field, std::uint32_t)
Definition STObject.cpp:718
bool isFieldPresent(SField const &field) const
Definition STObject.cpp:439
bool setFlag(std::uint32_t)
Definition STObject.cpp:462
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:513
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:445
std::string to_string(base_uint< Bits, Tag > const &a)
Definition base_uint.h:597
@ soeREQUIRED
Definition SOTemplate.h:15
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:213
constexpr std::uint32_t vfFullyCanonicalSig
T str(T... args)
T time_since_epoch(T... args)