rippled
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 <ripple/basics/FeeUnits.h>
24 #include <ripple/basics/Log.h>
25 #include <ripple/protocol/PublicKey.h>
26 #include <ripple/protocol/STObject.h>
27 #include <ripple/protocol/SecretKey.h>
28 #include <cassert>
29 #include <cstdint>
30 #include <functional>
31 #include <memory>
32 #include <optional>
33 
34 namespace ripple {
35 
36 // Validation flags
37 
38 // This is a full (as opposed to a partial) validation
39 constexpr std::uint32_t vfFullValidation = 0x00000001;
40 
41 // The signature is fully canonical
42 constexpr std::uint32_t vfFullyCanonicalSig = 0x80000000;
43 
44 class 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.
57  NodeID const nodeID_;
58 
60 
61 public:
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
98  uint256
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 private:
145  static SOTemplate const&
147 
148  STBase*
149  copy(std::size_t n, void* buf) const override;
150  STBase*
151  move(std::size_t n, void* buf) override;
152 
153  friend class detail::STVar;
154 };
155 
156 template <class LookupNodeID>
158  SerialIter& sit,
159  LookupNodeID&& lookupNodeID,
160  bool checkSignature)
162  , signingPubKey_([this]() {
163  auto const spk = getFieldVL(sfSigningPubKey);
164 
166  Throw<std::runtime_error>("Invalid public key in validation");
167 
168  return PublicKey{makeSlice(spk)};
169  }())
170  , nodeID_(lookupNodeID(signingPubKey_))
171 {
172  if (checkSignature && !isValid())
173  {
174  JLOG(debugLog().error()) << "Invalid signature in validation: "
176  Throw<std::runtime_error>("Invalid signature in validation");
177  }
178 
179  assert(nodeID_.isNonZero());
180 }
181 
190 template <typename F>
192  NetClock::time_point signTime,
193  PublicKey const& pk,
194  SecretKey const& sk,
195  NodeID const& nodeID,
196  F&& f)
198  , signingPubKey_(pk)
199  , nodeID_(nodeID)
200  , seenTime_(signTime)
201 {
202  assert(nodeID_.isNonZero());
203 
204  // First, set our own public key:
206  LogicError("We can only use secp256k1 keys for signing validations");
207 
209  setFieldU32(sfSigningTime, signTime.time_since_epoch().count());
210 
211  // Perform additional initialization
212  f(*this);
213 
214  // Finally, sign the validation and mark it as trusted:
217  setTrusted();
218 
219  // Check to ensure that all required fields are present.
220  for (auto const& e : validationFormat())
221  {
222  if (e.style() == soeREQUIRED && !isFieldPresent(e.sField()))
223  LogicError(
224  "Required field '" + e.sField().getName() +
225  "' missing from validation.");
226  }
227 
228  // We just signed this, so it should be valid.
229  valid_ = true;
230 }
231 
232 inline PublicKey const&
234 {
235  return signingPubKey_;
236 }
237 
238 inline NodeID const&
239 STValidation::getNodeID() const noexcept
240 {
241  return nodeID_;
242 }
243 
244 inline bool
245 STValidation::isTrusted() const noexcept
246 {
247  return mTrusted;
248 }
249 
250 inline void
252 {
253  mTrusted = true;
254 }
255 
256 inline void
258 {
259  mTrusted = false;
260 }
261 
262 inline void
264 {
265  seenTime_ = s;
266 }
267 
268 } // namespace ripple
269 
270 #endif
ripple::STValidation::nodeID_
const NodeID nodeID_
Definition: STValidation.h:57
ripple::makeSlice
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:241
ripple::STValidation::getConsensusHash
uint256 getConsensusHash() const
Definition: STValidation.cpp:88
ripple::CountedObject
Tracks the number of instances of an object.
Definition: CountedObject.h:124
ripple::base_uint::isNonZero
bool isNonZero() const
Definition: base_uint.h:537
functional
std::vector< unsigned char >
ripple::sfSigningPubKey
const SF_VL sfSigningPubKey
ripple::STValidation::getLedgerHash
uint256 getLedgerHash() const
Definition: STValidation.cpp:82
ripple::STValidation::signingPubKey_
const PublicKey signingPubKey_
Definition: STValidation.h:53
ripple::STValidation::getNodeID
NodeID const & getNodeID() const noexcept
Definition: STValidation.h:239
ripple::STValidation::mTrusted
bool mTrusted
Definition: STValidation.h:46
ripple::PublicKey::slice
Slice slice() const noexcept
Definition: PublicKey.h:123
ripple::soeREQUIRED
@ soeREQUIRED
Definition: SOTemplate.h:35
ripple::STValidation::copy
STBase * copy(std::size_t n, void *buf) const override
Definition: STValidation.cpp:29
ripple::STObject::setFieldVL
void setFieldVL(SField const &field, Blob const &)
Definition: STObject.cpp:695
ripple::STObject::getFieldVL
Blob getFieldVL(SField const &field) const
Definition: STObject.cpp:595
ripple::STValidation::validationFormat
static SOTemplate const & validationFormat()
Definition: STValidation.cpp:41
ripple::STValidation::getSignature
Blob getSignature() const
Definition: STValidation.cpp:129
ripple::debugLog
beast::Journal debugLog()
Returns a debug journal.
Definition: Log.cpp:452
ripple::STValidation::isTrusted
bool isTrusted() const noexcept
Definition: STValidation.h:245
ripple::STValidation
Definition: STValidation.h:44
ripple::vfFullyCanonicalSig
constexpr std::uint32_t vfFullyCanonicalSig
Definition: STValidation.h:42
ripple::publicKeyType
std::optional< KeyType > publicKeyType(Slice const &slice)
Returns the type of public key.
Definition: PublicKey.cpp:207
ripple::base_uint< 160, detail::NodeIDTag >
std::chrono::time_point::time_since_epoch
T time_since_epoch(T... args)
ripple::SOTemplate
Defines the fields and their attributes within a STObject.
Definition: SOTemplate.h:82
ripple::STValidation::getSignerPublic
PublicKey const & getSignerPublic() const noexcept
Definition: STValidation.h:233
ripple::STValidation::valid_
std::optional< bool > valid_
Definition: STValidation.h:50
ripple::PublicKey
A public key.
Definition: PublicKey.h:59
ripple::signDigest
Buffer signDigest(PublicKey const &pk, SecretKey const &sk, uint256 const &digest)
Generate a signature for a message digest.
Definition: SecretKey.cpp:212
ripple::JsonOptions::none
@ none
ripple::STValidation::getSerialized
Blob getSerialized() const
Definition: STValidation.cpp:135
ripple::STValidation::move
STBase * move(std::size_t n, void *buf) override
Definition: STValidation.cpp:35
ripple::STValidation::isFull
bool isFull() const noexcept
Definition: STValidation.cpp:123
std::chrono::time_point
cstdint
ripple::STValidation::setSeen
void setSeen(NetClock::time_point s)
Definition: STValidation.h:263
ripple::SerialIter
Definition: Serializer.h:310
std::uint32_t
ripple::SecretKey
A secret key.
Definition: SecretKey.h:36
ripple::STValidation::getSignTime
NetClock::time_point getSignTime() const
Definition: STValidation.cpp:94
memory
ripple::STValidation::seenTime_
NetClock::time_point seenTime_
Definition: STValidation.h:59
ripple::STValidation::isValid
bool isValid() const noexcept
Definition: STValidation.cpp:106
ripple::STValidation::setUntrusted
void setUntrusted()
Definition: STValidation.h:257
ripple::KeyType::secp256k1
@ secp256k1
ripple::STObject
Definition: STObject.h:51
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::STBase
A type which can be exported to a well known binary format.
Definition: STBase.h:66
std
STL namespace.
ripple::LogicError
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
Definition: contract.cpp:48
ripple::STObject::isFieldPresent
bool isFieldPresent(SField const &field) const
Definition: STObject.cpp:428
cassert
ripple::STValidation::setTrusted
void setTrusted()
Definition: STValidation.h:251
ripple::sfSignature
const SF_VL sfSignature
ripple::STValidation::getSeenTime
NetClock::time_point getSeenTime() const noexcept
Definition: STValidation.cpp:100
ripple::STObject::setFlag
bool setFlag(std::uint32_t)
Definition: STObject.cpp:451
ripple::STValidation::getSigningHash
uint256 getSigningHash() const
Definition: STValidation.cpp:76
ripple::sfValidation
const SField sfValidation
optional
ripple::vfFullValidation
constexpr std::uint32_t vfFullValidation
Definition: STValidation.h:39
ripple::NetClock
Clock for measuring the network time.
Definition: chrono.h:48
ripple::STObject::getJson
Json::Value getJson(JsonOptions options) const override
Definition: STObject.cpp:725
ripple::STObject::setFieldU32
void setFieldU32(SField const &field, std::uint32_t)
Definition: STObject.cpp:659
ripple::sfSigningTime
const SF_UINT32 sfSigningTime
ripple::STValidation::STValidation
STValidation(SerialIter &sit, LookupNodeID &&lookupNodeID, bool checkSignature)
Construct a STValidation from a peer from serialized data.
Definition: STValidation.h:157