rippled
Loading...
Searching...
No Matches
STValidation.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#ifndef RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
21#define RIPPLE_PROTOCOL_STVALIDATION_H_INCLUDED
22
23#include <xrpl/basics/Log.h>
24#include <xrpl/beast/utility/instrumentation.h>
25#include <xrpl/protocol/FeeUnits.h>
26#include <xrpl/protocol/PublicKey.h>
27#include <xrpl/protocol/STObject.h>
28#include <xrpl/protocol/SecretKey.h>
29#include <cstdint>
30#include <functional>
31#include <memory>
32#include <optional>
33#include <sstream>
34
35namespace ripple {
36
37// Validation flags
38
39// This is a full (as opposed to a partial) validation
40constexpr std::uint32_t vfFullValidation = 0x00000001;
41
42// The signature is fully canonical
43constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
44
45class STValidation final : public STObject, public CountedObject<STValidation>
46{
47 bool mTrusted = false;
48
49 // Determines the validity of the signature in this validation; unseated
50 // optional if we haven't yet checked it, a boolean otherwise.
52
53 // The public key associated with the key used to sign this validation
55
56 // The ID of the validator that issued this validation. For validators
57 // that use manifests this will be derived from the master public key.
59
61
62public:
76 template <class LookupNodeID>
78 SerialIter& sit,
79 LookupNodeID&& lookupNodeID,
80 bool checkSignature);
81
90 template <typename F>
92 NetClock::time_point signTime,
93 PublicKey const& pk,
94 SecretKey const& sk,
95 NodeID const& nodeID,
96 F&& f);
97
98 // Hash of the validated ledger
100 getLedgerHash() const;
101
102 // Hash of consensus transaction set used to generate ledger
103 uint256
104 getConsensusHash() const;
105
107 getSignTime() const;
108
110 getSeenTime() const noexcept;
111
112 PublicKey const&
113 getSignerPublic() const noexcept;
114
115 NodeID const&
116 getNodeID() const noexcept;
117
118 bool
119 isValid() const noexcept;
120
121 bool
122 isFull() const noexcept;
123
124 bool
125 isTrusted() const noexcept;
126
127 uint256
128 getSigningHash() const;
129
130 void
131 setTrusted();
132
133 void
134 setUntrusted();
135
136 void
137 setSeen(NetClock::time_point s);
138
139 Blob
140 getSerialized() const;
141
142 Blob
143 getSignature() const;
144
145 std::string
146 render() const
147 {
149 ss << "validation: "
150 << " ledger_hash: " << getLedgerHash()
151 << " consensus_hash: " << getConsensusHash()
152 << " sign_time: " << to_string(getSignTime())
153 << " seen_time: " << to_string(getSeenTime())
154 << " signer_public_key: " << getSignerPublic()
155 << " node_id: " << getNodeID() << " is_valid: " << isValid()
156 << " is_full: " << isFull() << " is_trusted: " << isTrusted()
157 << " signing_hash: " << getSigningHash()
158 << " base58: " << toBase58(TokenType::NodePublic, getSignerPublic());
159 return ss.str();
160 }
161
162private:
163 static SOTemplate const&
165
166 STBase*
167 copy(std::size_t n, void* buf) const override;
168 STBase*
169 move(std::size_t n, void* buf) override;
170
171 friend class detail::STVar;
172};
173
174template <class LookupNodeID>
176 SerialIter& sit,
177 LookupNodeID&& lookupNodeID,
178 bool checkSignature)
179 : STObject(validationFormat(), sit, sfValidation)
180 , signingPubKey_([this]() {
181 auto const spk = getFieldVL(sfSigningPubKey);
182
184 Throw<std::runtime_error>("Invalid public key in validation");
185
186 return PublicKey{makeSlice(spk)};
187 }())
188 , nodeID_(lookupNodeID(signingPubKey_))
189{
190 if (checkSignature && !isValid())
191 {
192 JLOG(debugLog().error()) << "Invalid signature in validation: "
194 Throw<std::runtime_error>("Invalid signature in validation");
195 }
196
197 XRPL_ASSERT(
198 nodeID_.isNonZero(),
199 "ripple::STValidation::STValidation(SerialIter) : nonzero node");
200}
201
210template <typename F>
212 NetClock::time_point signTime,
213 PublicKey const& pk,
214 SecretKey const& sk,
215 NodeID const& nodeID,
216 F&& f)
217 : STObject(validationFormat(), sfValidation)
218 , signingPubKey_(pk)
219 , nodeID_(nodeID)
220 , seenTime_(signTime)
221{
222 XRPL_ASSERT(
224 "ripple::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
225 "node");
226
227 // First, set our own public key:
229 LogicError("We can only use secp256k1 keys for signing validations");
230
231 setFieldVL(sfSigningPubKey, pk.slice());
232 setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
233
234 // Perform additional initialization
235 f(*this);
236
237 // Finally, sign the validation and mark it as trusted:
239 setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
240 setTrusted();
241
242 // Check to ensure that all required fields are present.
243 for (auto const& e : validationFormat())
244 {
245 if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
247 "Required field '" + e.sField().getName() +
248 "' missing from validation.");
249 }
250
251 // We just signed this, so it should be valid.
252 valid_ = true;
253}
254
255inline PublicKey const&
257{
258 return signingPubKey_;
259}
260
261inline NodeID const&
263{
264 return nodeID_;
265}
266
267inline bool
269{
270 return mTrusted;
271}
272
273inline void
275{
276 mTrusted = true;
277}
278
279inline void
281{
282 mTrusted = false;
283}
284
285inline void
287{
288 seenTime_ = s;
289}
290
291} // namespace ripple
292
293#endif
Tracks the number of instances of an object.
A public key.
Definition: PublicKey.h:62
Slice slice() const noexcept
Definition: PublicKey.h:123
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:113
A type which can be exported to a well known binary format.
Definition: STBase.h:124
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:627
bool setFlag(std::uint32_t)
Definition: STObject.cpp:477
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:454
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:711
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:747
PublicKey const & getSignerPublic() const noexcept
Definition: STValidation.h:256
uint256 getConsensusHash() const
std::string render() const
Definition: STValidation.h:146
std::optional< bool > valid_
Definition: STValidation.h:51
STValidation(SerialIter &sit, LookupNodeID &&lookupNodeID, bool checkSignature)
Construct a STValidation from a peer from serialized data.
Definition: STValidation.h:175
Blob getSerialized() const
NetClock::time_point getSeenTime() const noexcept
void setSeen(NetClock::time_point s)
Definition: STValidation.h:286
bool isTrusted() const noexcept
Definition: STValidation.h:268
NodeID const nodeID_
Definition: STValidation.h:58
PublicKey const signingPubKey_
Definition: STValidation.h:54
static SOTemplate const & validationFormat()
NodeID const & getNodeID() const noexcept
Definition: STValidation.h:262
bool isFull() const noexcept
NetClock::time_point seenTime_
Definition: STValidation.h:60
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:37
bool isNonZero() const
Definition: base_uint.h:544
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
Definition: AccountID.cpp:106
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
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:243
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:452
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
Definition: SecretKey.cpp:212
constexpr std::uint32_t vfFullyCanonicalSig
Definition: STValidation.h:43
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:629
constexpr std::uint32_t vfFullValidation
Definition: STValidation.h:40
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
@ soeREQUIRED
Definition: SOTemplate.h:35
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
STL namespace.
T str(T... args)
T time_since_epoch(T... args)