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
30#include <cstdint>
31#include <functional>
32#include <memory>
33#include <optional>
34#include <sstream>
35
36namespace ripple {
37
38// Validation flags
39
40// This is a full (as opposed to a partial) validation
41constexpr std::uint32_t vfFullValidation = 0x00000001;
42
43// The signature is fully canonical
44constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
45
46class STValidation final : public STObject, public CountedObject<STValidation>
47{
48 bool mTrusted = false;
49
50 // Determines the validity of the signature in this validation; unseated
51 // optional if we haven't yet checked it, a boolean otherwise.
53
54 // The public key associated with the key used to sign this validation
56
57 // The ID of the validator that issued this validation. For validators
58 // that use manifests this will be derived from the master public key.
60
62
63public:
77 template <class LookupNodeID>
79 SerialIter& sit,
80 LookupNodeID&& lookupNodeID,
81 bool checkSignature);
82
91 template <typename F>
93 NetClock::time_point signTime,
94 PublicKey const& pk,
95 SecretKey const& sk,
96 NodeID const& nodeID,
97 F&& f);
98
99 // Hash of the validated ledger
100 uint256
101 getLedgerHash() const;
102
103 // Hash of consensus transaction set used to generate ledger
104 uint256
105 getConsensusHash() const;
106
108 getSignTime() const;
109
111 getSeenTime() const noexcept;
112
113 PublicKey const&
114 getSignerPublic() const noexcept;
115
116 NodeID const&
117 getNodeID() const noexcept;
118
119 bool
120 isValid() const noexcept;
121
122 bool
123 isFull() const noexcept;
124
125 bool
126 isTrusted() const noexcept;
127
128 uint256
129 getSigningHash() const;
130
131 void
132 setTrusted();
133
134 void
135 setUntrusted();
136
137 void
138 setSeen(NetClock::time_point s);
139
140 Blob
141 getSerialized() const;
142
143 Blob
144 getSignature() const;
145
146 std::string
147 render() const
148 {
150 ss << "validation: " << " 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:114
A type which can be exported to a well known binary format.
Definition: STBase.h:126
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:657
bool setFlag(std::uint32_t)
Definition: STObject.cpp:507
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:484
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:741
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:777
PublicKey const & getSignerPublic() const noexcept
Definition: STValidation.h:256
uint256 getConsensusHash() const
std::string render() const
Definition: STValidation.h:147
std::optional< bool > valid_
Definition: STValidation.h:52
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:59
PublicKey const signingPubKey_
Definition: STValidation.h:55
static SOTemplate const & validationFormat()
NodeID const & getNodeID() const noexcept
Definition: STValidation.h:262
bool isFull() const noexcept
NetClock::time_point seenTime_
Definition: STValidation.h:61
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:38
bool isNonZero() const
Definition: base_uint.h:545
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:114
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:223
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:244
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:468
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
Definition: SecretKey.cpp:230
constexpr std::uint32_t vfFullyCanonicalSig
Definition: STValidation.h:44
std::string to_string(base_uint< Bits, Tag > const &a)
Definition: base_uint.h:630
constexpr std::uint32_t vfFullValidation
Definition: STValidation.h:41
Json::Value getJson(LedgerFill const &fill)
Return a new Json::Value representing the ledger with given options.
@ soeREQUIRED
Definition: SOTemplate.h:36
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:37
STL namespace.
T str(T... args)
T time_since_epoch(T... args)