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/PublicKey.h>
26#include <xrpl/protocol/STObject.h>
27#include <xrpl/protocol/SecretKey.h>
28#include <xrpl/protocol/Units.h>
29
30#include <cstdint>
31#include <optional>
32#include <sstream>
33
34namespace ripple {
35
36// Validation flags
37
38// This is a full (as opposed to a partial) validation
39constexpr std::uint32_t vfFullValidation = 0x00000001;
40
41// The signature is fully canonical
42constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
43
44class STValidation final : public STObject, public CountedObject<STValidation>
45{
46 bool mTrusted = false;
47
48 // Determines the validity of the signature in this validation; unseated
49 // optional if we haven't yet checked it, a boolean otherwise.
51
52 // The public key associated with the key used to sign this validation
54
55 // The ID of the validator that issued this validation. For validators
56 // that use manifests this will be derived from the master public key.
58
60
61public:
75 template <class LookupNodeID>
77 SerialIter& sit,
78 LookupNodeID&& lookupNodeID,
79 bool checkSignature);
80
89 template <typename F>
91 NetClock::time_point signTime,
92 PublicKey const& pk,
93 SecretKey const& sk,
94 NodeID const& nodeID,
95 F&& f);
96
97 // Hash of the validated ledger
99 getLedgerHash() const;
100
101 // Hash of consensus transaction set used to generate ledger
102 uint256
103 getConsensusHash() const;
104
106 getSignTime() const;
107
109 getSeenTime() const noexcept;
110
111 PublicKey const&
112 getSignerPublic() const noexcept;
113
114 NodeID const&
115 getNodeID() const noexcept;
116
117 bool
118 isValid() const noexcept;
119
120 bool
121 isFull() const noexcept;
122
123 bool
124 isTrusted() const noexcept;
125
126 uint256
127 getSigningHash() const;
128
129 void
130 setTrusted();
131
132 void
133 setUntrusted();
134
135 void
136 setSeen(NetClock::time_point s);
137
138 Blob
139 getSerialized() const;
140
141 Blob
142 getSignature() const;
143
144 std::string
145 render() const
146 {
148 ss << "validation: " << " ledger_hash: " << getLedgerHash()
149 << " consensus_hash: " << getConsensusHash()
150 << " sign_time: " << to_string(getSignTime())
151 << " seen_time: " << to_string(getSeenTime())
152 << " signer_public_key: " << getSignerPublic()
153 << " node_id: " << getNodeID() << " is_valid: " << isValid()
154 << " is_full: " << isFull() << " is_trusted: " << isTrusted()
155 << " signing_hash: " << getSigningHash()
156 << " base58: " << toBase58(TokenType::NodePublic, getSignerPublic());
157 return ss.str();
158 }
159
160private:
161 static SOTemplate const&
163
164 STBase*
165 copy(std::size_t n, void* buf) const override;
166 STBase*
167 move(std::size_t n, void* buf) override;
168
169 friend class detail::STVar;
170};
171
172template <class LookupNodeID>
174 SerialIter& sit,
175 LookupNodeID&& lookupNodeID,
176 bool checkSignature)
177 : STObject(validationFormat(), sit, sfValidation)
178 , signingPubKey_([this]() {
179 auto const spk = getFieldVL(sfSigningPubKey);
180
182 Throw<std::runtime_error>("Invalid public key in validation");
183
184 return PublicKey{makeSlice(spk)};
185 }())
186 , nodeID_(lookupNodeID(signingPubKey_))
187{
188 if (checkSignature && !isValid())
189 {
190 JLOG(debugLog().error()) << "Invalid signature in validation: "
192 Throw<std::runtime_error>("Invalid signature in validation");
193 }
194
195 XRPL_ASSERT(
196 nodeID_.isNonZero(),
197 "ripple::STValidation::STValidation(SerialIter) : nonzero node");
198}
199
208template <typename F>
210 NetClock::time_point signTime,
211 PublicKey const& pk,
212 SecretKey const& sk,
213 NodeID const& nodeID,
214 F&& f)
215 : STObject(validationFormat(), sfValidation)
216 , signingPubKey_(pk)
217 , nodeID_(nodeID)
218 , seenTime_(signTime)
219{
220 XRPL_ASSERT(
222 "ripple::STValidation::STValidation(PublicKey, SecretKey) : nonzero "
223 "node");
224
225 // First, set our own public key:
227 LogicError("We can only use secp256k1 keys for signing validations");
228
229 setFieldVL(sfSigningPubKey, pk.slice());
230 setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
231
232 // Perform additional initialization
233 f(*this);
234
235 // Finally, sign the validation and mark it as trusted:
237 setFieldVL(sfSignature, signDigest(pk, sk, getSigningHash()));
238 setTrusted();
239
240 // Check to ensure that all required fields are present.
241 for (auto const& e : validationFormat())
242 {
243 if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
245 "Required field '" + e.sField().getName() +
246 "' missing from validation.");
247 }
248
249 // We just signed this, so it should be valid.
250 valid_ = true;
251}
252
253inline PublicKey const&
255{
256 return signingPubKey_;
257}
258
259inline NodeID const&
261{
262 return nodeID_;
263}
264
265inline bool
267{
268 return mTrusted;
269}
270
271inline void
273{
274 mTrusted = true;
275}
276
277inline void
279{
280 mTrusted = false;
281}
282
283inline void
288
289} // namespace ripple
290
291#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:135
Blob getFieldVL(SField const &field) const
Definition STObject.cpp:663
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:757
void setFieldVL(SField const &field, Blob const &)
Definition STObject.cpp:799
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: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:25
std::string toBase58(AccountID const &v)
Convert AccountID to base58 checked string.
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:244
beast::Journal debugLog()
Returns a debug journal.
Definition Log.cpp:476
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:630
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:35
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)