xrpld
Loading...
Searching...
No Matches
Fulfillment.cpp
1#include <xrpl/conditions/Fulfillment.h>
2
3#include <xrpl/basics/Slice.h>
4#include <xrpl/basics/safe_cast.h>
5#include <xrpl/conditions/Condition.h>
6#include <xrpl/conditions/detail/PreimageSha256.h>
7#include <xrpl/conditions/detail/error.h>
8#include <xrpl/conditions/detail/utils.h>
9
10#include <memory>
11#include <system_error>
12
13namespace xrpl::cryptoconditions {
14
15bool
16match(Fulfillment const& f, Condition const& c)
17{
18 // Fast check: the fulfillment's type must match the
19 // conditions's type:
20 if (f.type() != c.type)
21 return false;
22
23 // Derive the condition from the given fulfillment
24 // and ensure that it matches the given condition.
25 return c == f.condition();
26}
27
28bool
29validate(Fulfillment const& f, Condition const& c, Slice m)
30{
31 return match(f, c) && f.validate(m);
32}
33
34bool
35validate(Fulfillment const& f, Condition const& c)
36{
37 return validate(f, c, {});
38}
39
42{
43 // Per the RFC, in a fulfillment we choose a type based
44 // on the tag of the item we contain:
45 //
46 // Fulfillment ::= CHOICE {
47 // preimageSha256 [0] PreimageFulfillment ,
48 // prefixSha256 [1] PrefixFulfillment,
49 // thresholdSha256 [2] ThresholdFulfillment,
50 // rsaSha256 [3] RsaSha256Fulfillment,
51 // ed25519Sha256 [4] Ed25519Sha512Fulfillment
52 // }
53
54 if (s.empty())
55 {
57 return nullptr;
58 }
59
60 using namespace der;
61
62 auto const p = parsePreamble(s, ec);
63 if (ec)
64 return nullptr;
65
66 // All fulfillments are context-specific, constructed types
67 if (!isConstructed(p) || !isContextSpecific(p))
68 {
70 return nullptr;
71 }
72
73 if (p.length > s.size())
74 {
76 return {};
77 }
78
79 if (p.length < s.size())
80 {
82 return {};
83 }
84
85 if (p.length > kMaxSerializedFulfillment)
86 {
88 return {};
89 }
90
92
93 using TagType = decltype(p.tag);
94 switch (p.tag)
95 {
97 f = PreimageSha256::deserialize(Slice(s.data(), p.length), ec);
98 if (ec)
99 return {};
100 s += p.length;
101 break;
102
108 return {};
109
110 default:
112 return {};
113 }
114
115 if (!s.empty())
116 {
118 return {};
119 }
120
121 return f;
122}
123
124} // namespace xrpl::cryptoconditions
An immutable linear range of bytes.
Definition Slice.h:26
std::size_t length() const noexcept
Definition Slice.h:67
bool empty() const noexcept
Return true if the byte range is empty.
Definition Slice.h:50
std::uint8_t const * data() const noexcept
Return a pointer to beginning of the storage.
Definition Slice.h:78
std::size_t size() const noexcept
Returns the number of bytes in the storage.
Definition Slice.h:61
static std::unique_ptr< Fulfillment > deserialize(Slice s, std::error_code &ec)
Parse the payload for a PreimageSha256 condition.
bool match(Fulfillment const &f, Condition const &c)
Determine whether the given fulfillment and condition match.
bool validate(Fulfillment const &f, Condition const &c, Slice m)
Verify if the given message satisfies the fulfillment.
constexpr std::enable_if_t< std::is_integral_v< Dest > &&std::is_integral_v< Src >, Dest > safeCast(Src s) noexcept
Definition safe_cast.h:21
static std::unique_ptr< Fulfillment > deserialize(Slice s, std::error_code &ec)
Load a fulfillment from its binary form.
virtual Condition condition() const =0
Returns the condition associated with the given fulfillment.
virtual Type type() const =0
Returns the type of this condition.
virtual bool validate(Slice data) const =0
Validates a fulfillment.
static constexpr std::size_t kMaxSerializedFulfillment
The largest binary fulfillment we support.
Definition Fulfillment.h:19