BitShares-Core  7.0.2
BitShares blockchain node software and command-line wallet software
htlc_evaluator.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018 jmjatlanta and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
27 #include <graphene/chain/hardfork.hpp>
29 
30 namespace graphene {
31  namespace chain {
32  namespace detail
33  {
35  const htlc_create_operation& op, const asset_object& asset_to_transfer)
36  {
37  if (block_time < HARDFORK_CORE_BSIP64_TIME)
38  {
39  // memo field added at harfork BSIP64
40  // NOTE: both of these checks can be removed after hardfork time
41  FC_ASSERT( !op.extensions.value.memo.valid(),
42  "Memo unavailable until after HARDFORK BSIP64");
43  // HASH160 added at hardfork BSIP64
45  "HASH160 unavailable until after HARDFORK BSIP64" );
46  }
47  else
48  {
49  // this can be moved to the normal non-hf checks after HF_BSIP64
50  // IF there were no restricted transfers before HF_BSIP64
51  FC_ASSERT( !asset_to_transfer.is_transfer_restricted()
52  || op.from == asset_to_transfer.issuer || op.to == asset_to_transfer.issuer,
53  "Asset ${asset} cannot be transfered.", ("asset", asset_to_transfer.id) );
54  }
55  }
56 
58  const htlc_redeem_operation& op, const htlc_object* htlc_obj)
59  {
60  // TODO: The hardfork portion of this check can be removed if no HTLC redemptions are
61  // attempted on an HTLC with a 0 preimage size before the hardfork date.
62  if ( htlc_obj->conditions.hash_lock.preimage_size > 0U ||
63  block_time < HARDFORK_CORE_BSIP64_TIME )
64  FC_ASSERT(op.preimage.size() == htlc_obj->conditions.hash_lock.preimage_size,
65  "Preimage size mismatch.");
66  }
67  } // end of graphene::chain::details
68 
70  {
71  return db.get_global_properties().parameters.extensions.value.updatable_htlc_options;
72  }
73 
75  {
78 
79  FC_ASSERT(htlc_options, "HTLC Committee options are not set.");
80 
81  // make sure the expiration is reasonable
83  "HTLC Timeout exceeds allowed length" );
84  // make sure the preimage length is reasonable
86  "HTLC preimage length exceeds allowed length" );
87  // make sure the sender has the funds for the HTLC
88  FC_ASSERT( d.get_balance( o.from, o.amount.asset_id) >= (o.amount), "Insufficient funds") ;
89  const auto& asset_to_transfer = o.amount.asset_id( d );
90  const auto& from_account = o.from( d );
91  const auto& to_account = o.to( d );
92  detail::check_htlc_create_hf_bsip64(d.head_block_time(), o, asset_to_transfer);
93  FC_ASSERT( is_authorized_asset( d, from_account, asset_to_transfer ),
94  "Asset ${asset} is not authorized for account ${acct}.",
95  ( "asset", asset_to_transfer.id )( "acct", from_account.id ) );
96  FC_ASSERT( is_authorized_asset( d, to_account, asset_to_transfer ),
97  "Asset ${asset} is not authorized for account ${acct}.",
98  ( "asset", asset_to_transfer.id )( "acct", to_account.id ) );
99  return void_result();
100  }
101 
103  {
104  try {
105  graphene::chain::database& dbase = db();
106  dbase.adjust_balance( o.from, -o.amount );
107 
108  const htlc_object& esc = db().create<htlc_object>([&dbase,&o]( htlc_object& esc ) {
109  esc.transfer.from = o.from;
110  esc.transfer.to = o.to;
111  esc.transfer.amount = o.amount.amount;
115  if ( o.extensions.value.memo.valid() )
116  esc.memo = o.extensions.value.memo;
117  esc.conditions.time_lock.expiration = dbase.head_block_time() + o.claim_period_seconds;
118  });
119  return esc.id;
120 
121  } FC_CAPTURE_AND_RETHROW( (o) )
122  }
123 
125  {
126  //private:
127  const std::vector<char>& data;
128  public:
129  typedef bool result_type;
130 
131  htlc_redeem_visitor( const std::vector<char>& preimage )
132  : data( preimage ) {}
133 
134  template<typename T>
135  bool operator()( const T& preimage_hash )const
136  {
137  return T::hash( (const char*)data.data(), (uint32_t) data.size() ) == preimage_hash;
138  }
139  };
140 
142  {
143  auto& d = db();
144  htlc_obj = &d.get(o.htlc_id);
145  detail::check_htlc_redeem_hf_bsip64(d.head_block_time(), o, htlc_obj);
146 
147  const htlc_redeem_visitor vtor( o.preimage );
149  "Provided preimage does not generate correct hash.");
150 
151  return void_result();
152  }
153 
155  {
156  const auto amount = asset(htlc_obj->transfer.amount, htlc_obj->transfer.asset_id);
157  db().adjust_balance(htlc_obj->transfer.to, amount);
158  // notify related parties
160  o.redeemer,
162  o.preimage );
163  db().push_applied_operation( virt_op );
164  db().remove(*htlc_obj);
165  return void_result();
166  }
167 
169  {
170  htlc_obj = &db().get(o.htlc_id);
171  FC_ASSERT(o.update_issuer == htlc_obj->transfer.from, "HTLC may only be extended by its creator.");
174  + static_cast<uint64_t>(o.seconds_to_add) < fc::time_point_sec::maximum().sec_since_epoch(),
175  "Extension would cause an invalid date");
177  <= db().head_block_time() + htlc_options->max_timeout_secs,
178  "Extension pushes contract too far into the future" );
179  return void_result();
180  }
181 
183  {
184  db().modify(*htlc_obj, [&o](htlc_object& db_obj) {
186  });
187 
188  return void_result();
189  }
190 
191  } // namespace chain
192 } // namespace graphene
graphene::chain::htlc_object::transfer_info::asset_id
asset_id_type asset_id
Definition: htlc_object.hpp:48
fc::time_point_sec::sec_since_epoch
uint32_t sec_since_epoch() const
Definition: time.hpp:90
FC_CAPTURE_AND_RETHROW
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:479
graphene::db::object::id
object_id_type id
Definition: object.hpp:69
is_authorized_asset.hpp
graphene::chain::detail::check_htlc_redeem_hf_bsip64
void check_htlc_redeem_hf_bsip64(const fc::time_point_sec &block_time, const htlc_redeem_operation &op, const htlc_object *htlc_obj)
Definition: htlc_evaluator.cpp:57
graphene::chain::database
tracks the blockchain state in an extensible manner
Definition: database.hpp:70
graphene::chain::htlc_redeem_visitor::htlc_redeem_visitor
htlc_redeem_visitor(const std::vector< char > &preimage)
Definition: htlc_evaluator.cpp:131
htlc_evaluator.hpp
graphene::chain::database::head_block_time
time_point_sec head_block_time() const
Definition: db_getter.cpp:67
graphene::chain::htlc_redeem_evaluator::do_apply
void_result do_apply(const htlc_redeem_operation &o)
Definition: htlc_evaluator.cpp:154
graphene::chain::htlc_object::condition_info::hash_lock
hash_lock_info hash_lock
Definition: htlc_object.hpp:61
graphene::db::object_database::get
const T & get(const object_id_type &id) const
Definition: object_database.hpp:119
graphene::chain::database::get_balance
asset get_balance(account_id_type owner, asset_id_type asset_id) const
Retrieve a particular account's balance in a given asset.
Definition: db_balance.cpp:35
database.hpp
graphene::protocol::htlc_create_operation::preimage_size
uint16_t preimage_size
Definition: htlc.hpp:63
graphene::protocol::htlc_redeem_operation
Definition: htlc.hpp:90
graphene::chain::htlc_redeem_visitor::operator()
bool operator()(const T &preimage_hash) const
Definition: htlc_evaluator.cpp:135
graphene::chain::global_property_object::parameters
chain_parameters parameters
Definition: global_property_object.hpp:44
graphene::protocol::htlc_redeem_operation::preimage
std::vector< char > preimage
Definition: htlc.hpp:104
graphene::protocol::htlc_create_operation::from
account_id_type from
Definition: htlc.hpp:55
graphene::chain::htlc_object::condition_info::time_lock
time_lock_info time_lock
Definition: htlc_object.hpp:62
graphene::chain::htlc_object::transfer_info::from
account_id_type from
Definition: htlc_object.hpp:45
graphene::chain::htlc_redeem_visitor::result_type
bool result_type
Definition: htlc_evaluator.cpp:129
graphene::chain::asset_object
tracks the parameters of an asset
Definition: asset_object.hpp:75
graphene::db::object_database::create
const T & create(F &&constructor)
Definition: object_database.hpp:63
graphene::chain::database::adjust_balance
void adjust_balance(account_id_type account, asset delta)
Adjust a particular account's balance in a given asset by a delta.
Definition: db_balance.cpp:54
graphene::chain::htlc_extend_evaluator::do_evaluate
void_result do_evaluate(const htlc_extend_operation &o)
Definition: htlc_evaluator.cpp:168
graphene::chain::asset_object::is_transfer_restricted
bool is_transfer_restricted() const
Definition: asset_object.hpp:94
graphene::chain::htlc_object::condition_info::time_lock_info::expiration
fc::time_point_sec expiration
Definition: htlc_object.hpp:59
graphene::protocol::htlc_extend_operation::htlc_id
htlc_id_type htlc_id
Definition: htlc.hpp:163
fc::time_point_sec::maximum
static time_point_sec maximum()
Definition: time.hpp:86
graphene::protocol::htlc_redeemed_operation
Definition: htlc.hpp:127
graphene::protocol::htlc_create_operation::to
account_id_type to
Definition: htlc.hpp:57
graphene::chain::htlc_create_evaluator::do_apply
object_id_type do_apply(const htlc_create_operation &o)
Definition: htlc_evaluator.cpp:102
graphene::chain::htlc_redeem_visitor
Definition: htlc_evaluator.cpp:124
graphene::protocol::htlc_create_operation
Definition: htlc.hpp:45
graphene::chain::htlc_object::transfer
transfer_info transfer
Definition: htlc_object.hpp:65
graphene::protocol::htlc_options::max_preimage_size
uint32_t max_preimage_size
Definition: chain_parameters.hpp:35
graphene::chain::htlc_object::transfer_info::to
account_id_type to
Definition: htlc_object.hpp:46
graphene::protocol::htlc_extend_operation::update_issuer
account_id_type update_issuer
Definition: htlc.hpp:165
graphene::protocol::chain_parameters::extensions
extension< ext > extensions
Definition: chain_parameters.hpp:90
graphene::chain::htlc_object::condition_info::hash_lock_info::preimage_hash
htlc_hash preimage_hash
Definition: htlc_object.hpp:54
graphene::protocol::htlc_options::max_timeout_secs
uint32_t max_timeout_secs
Definition: chain_parameters.hpp:34
fc::time_point_sec
Definition: time.hpp:74
graphene::protocol::asset::asset_id
asset_id_type asset_id
Definition: asset.hpp:37
graphene::chain::database::push_applied_operation
uint32_t push_applied_operation(const operation &op, bool is_virtual=true)
Definition: db_block.cpp:548
graphene::protocol::htlc_create_operation::amount
asset amount
Definition: htlc.hpp:59
htlc_object.hpp
graphene::protocol::htlc_redeem_operation::htlc_id
htlc_id_type htlc_id
Definition: htlc.hpp:100
graphene::chain::is_authorized_asset
bool is_authorized_asset(const database &d, const account_object &acct, const asset_object &asset_obj)
Definition: is_authorized_asset.hpp:43
graphene::chain::htlc_extend_evaluator::htlc_obj
const htlc_object * htlc_obj
Definition: htlc_evaluator.hpp:57
graphene::chain::htlc_object::condition_info::hash_lock_info::preimage_size
uint16_t preimage_size
Definition: htlc_object.hpp:55
graphene::chain::htlc_object::transfer_info::amount
share_type amount
Definition: htlc_object.hpp:47
graphene::protocol::htlc_options
Definition: chain_parameters.hpp:32
graphene::chain::htlc_redeem_evaluator::do_evaluate
void_result do_evaluate(const htlc_redeem_operation &o)
Definition: htlc_evaluator.cpp:141
graphene::chain::generic_evaluator::db
database & db() const
Definition: evaluator.cpp:39
graphene::chain::htlc_create_evaluator::do_evaluate
void_result do_evaluate(const htlc_create_operation &o)
Definition: htlc_evaluator.cpp:74
graphene::protocol::htlc_create_operation::preimage_hash
htlc_hash preimage_hash
Definition: htlc.hpp:61
FC_ASSERT
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
graphene::chain::asset_object::issuer
account_id_type issuer
ID of the account which issued this asset.
Definition: asset_object.hpp:135
fc::static_variant::is_type
bool is_type() const
Definition: static_variant.hpp:332
graphene::db::object_id_type
Definition: object_id.hpp:30
graphene::protocol::asset::amount
share_type amount
Definition: asset.hpp:36
graphene::chain::htlc_object::conditions
condition_info conditions
Definition: htlc_object.hpp:66
graphene::chain::detail::check_htlc_create_hf_bsip64
void check_htlc_create_hf_bsip64(const fc::time_point_sec &block_time, const htlc_create_operation &op, const asset_object &asset_to_transfer)
Definition: htlc_evaluator.cpp:34
graphene::protocol::htlc_extend_operation
Definition: htlc.hpp:153
graphene::db::abstract_object::get_id
object_id< SpaceID, TypeID > get_id() const
Definition: object.hpp:113
fc::static_variant::visit
visitor::result_type visit(visitor &v)
Definition: static_variant.hpp:256
graphene::chain::htlc_redeem_evaluator::htlc_obj
const htlc_object * htlc_obj
Definition: htlc_evaluator.hpp:47
graphene::chain::database::get_global_properties
const global_property_object & get_global_properties() const
Definition: db_getter.cpp:47
fc::optional
provides stack-based nullable value similar to boost::optional
Definition: optional.hpp:20
graphene::protocol::htlc_redeem_operation::redeemer
account_id_type redeemer
Definition: htlc.hpp:102
fc::hash160
Definition: hash160.hpp:32
graphene::protocol::asset
Definition: asset.hpp:31
graphene::chain::get_committee_htlc_options
optional< htlc_options > get_committee_htlc_options(graphene::chain::database &db)
Definition: htlc_evaluator.cpp:69
graphene::protocol::void_result
Definition: base.hpp:86
graphene::db::object_database::remove
void remove(const object &obj)
Definition: object_database.hpp:97
graphene::chain::htlc_extend_evaluator::do_apply
void_result do_apply(const htlc_extend_operation &o)
Definition: htlc_evaluator.cpp:182
graphene::chain::htlc_object::memo
fc::optional< memo_data > memo
Definition: htlc_object.hpp:67
graphene::protocol::htlc_extend_operation::seconds_to_add
uint32_t seconds_to_add
Definition: htlc.hpp:167
graphene::protocol::htlc_create_operation::extensions
extension< additional_options_type > extensions
Definition: htlc.hpp:72
graphene
Definition: api.cpp:48
graphene::chain::htlc_object
database object to store HTLCs
Definition: htlc_object.hpp:40
graphene::protocol::htlc_create_operation::claim_period_seconds
uint32_t claim_period_seconds
Definition: htlc.hpp:65
graphene::db::object_database::modify
void modify(const T &obj, const Lambda &m)
Definition: object_database.hpp:99