Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hashed Time-Locked Contracts #1370

Merged
merged 56 commits into from
Dec 21, 2018
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
c6ca2c8
Initial HTLC commit
jmjatlanta Sep 5, 2018
bab9fb7
Fix compile errors
jmjatlanta Sep 5, 2018
81996c4
Fix tests
jmjatlanta Sep 5, 2018
3afa87e
added signature test
jmjatlanta Sep 7, 2018
6e960ef
Intermediate commit for adding htlc to wallet api
jmjatlanta Sep 14, 2018
f470aa3
Improvements to cli_wallet test
jmjatlanta Sep 16, 2018
b5510ac
Added update_htlc to wallet api
jmjatlanta Sep 17, 2018
40d22aa
Removed debugging code
jmjatlanta Sep 17, 2018
eb1225e
add htlc to switch-case
jmjatlanta Sep 27, 2018
d367c2c
Change method names to match spec
jmjatlanta Oct 12, 2018
6ded688
Boost 1.58 compatibility
jmjatlanta Oct 13, 2018
9a502a3
add get_typename for enum
jmjatlanta Oct 15, 2018
dc82610
Addition of SHA1 and committee parameters
jmjatlanta Oct 15, 2018
49822e1
Refactor committee parameters
jmjatlanta Oct 24, 2018
3ac8323
Test cleanup. Hardfork protection still needed.
jmjatlanta Oct 24, 2018
a30df56
modified name of optional committee parameters
jmjatlanta Oct 26, 2018
b5dae57
beginning of hardfork protection
jmjatlanta Oct 26, 2018
bc48b36
Code cleanup and comments
jmjatlanta Oct 29, 2018
5c5a0d7
Beginning of fee implementation
jmjatlanta Oct 29, 2018
ac29e84
committee fee flexibility and bug fixes
jmjatlanta Oct 30, 2018
50f6584
Calculate fees based on # days
jmjatlanta Oct 30, 2018
e8faf81
Added hardfork protection to proposal_create
jmjatlanta Nov 7, 2018
2c7f7f9
Removed debugging code
jmjatlanta Nov 7, 2018
68982ca
Added base16 to htlc hash for cli wallet
jmjatlanta Dec 11, 2018
44d4134
fix for redeem
jmjatlanta Dec 11, 2018
13926f5
Added details to history for HTLC create and redeem
jmjatlanta Dec 12, 2018
5103f7e
clearer text in account history
jmjatlanta Dec 12, 2018
2e5d74f
Adjust history lines
jmjatlanta Dec 13, 2018
d2dfa69
Modified wallet get_htlc to return pretty format
jmjatlanta Dec 13, 2018
4af8e6c
hash format fix
jmjatlanta Dec 13, 2018
5492797
Add pending info to HTLC in account history
jmjatlanta Dec 13, 2018
742f025
Fix htlc_prepare method signature
jmjatlanta Dec 13, 2018
b5b8dfc
Add virtual op for refund
jmjatlanta Dec 13, 2018
fe24161
Make refund appear in proper account
jmjatlanta Dec 13, 2018
27e2e75
Code cleanup pmconrad suggestions
jmjatlanta Dec 15, 2018
e563899
cleanup, consistent variable naming
jmjatlanta Dec 15, 2018
6239564
More consistent naming
jmjatlanta Dec 15, 2018
e914a37
Switch htlc object from implementation to protocol
jmjatlanta Dec 15, 2018
c808e61
Move committee parameter hardfork validation to visitor
jmjatlanta Dec 15, 2018
fea41d7
htlc_prepare is now htlc_create, plus start of fee testing (wip)
jmjatlanta Dec 17, 2018
e2e571a
1 day and 1kb mins on fees
jmjatlanta Dec 17, 2018
5c7a9e8
still trying to get fees working
jmjatlanta Dec 18, 2018
a2192ec
fix htlc fee tests
jmjatlanta Dec 19, 2018
f7d7f5c
Making fees work with htlc tests
jmjatlanta Dec 19, 2018
96ec5f3
move hash_algoritm enum plus misc
jmjatlanta Dec 19, 2018
0244ff5
Added missing (?) includes
pmconrad Dec 19, 2018
5ffa2a0
Get rid of floating point calculations
pmconrad Dec 19, 2018
145d790
Added hf protection for htlc_operations in proposals
pmconrad Dec 19, 2018
e255f39
Validate that preimage hash length matches algorithm hash length
pmconrad Dec 19, 2018
da6fbef
Refactoring: use a static_variant instead of separate enum + hash vector
pmconrad Dec 19, 2018
793220e
added extend test + smaller misc
jmjatlanta Dec 20, 2018
57248da
handle fee multiplication overflow
jmjatlanta Dec 20, 2018
e8172e9
added messages to asserts
jmjatlanta Dec 20, 2018
2f08968
virtual op for notifications
jmjatlanta Dec 21, 2018
22ea563
More overflow protection + wording changes
jmjatlanta Dec 21, 2018
8e77fff
fix bug in fee calculation
jmjatlanta Dec 21, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion libraries/chain/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ add_library( graphene_chain
protocol/fee_schedule.cpp
protocol/confidential.cpp
protocol/vote.cpp

protocol/htlc.cpp
genesis_state.cpp
get_config.cpp

Expand All @@ -77,6 +77,7 @@ add_library( graphene_chain
vesting_balance_evaluator.cpp
withdraw_permission_evaluator.cpp
worker_evaluator.cpp
htlc_evaluator.cpp
confidential_evaluator.cpp
special_authority.cpp
buyback.cpp
Expand Down
4 changes: 4 additions & 0 deletions libraries/chain/committee_member_evaluator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include <graphene/chain/committee_member_evaluator.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/database.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/account_object.hpp>
#include <graphene/chain/protocol/fee_schedule.hpp>
#include <graphene/chain/protocol/vote.hpp>
Expand Down Expand Up @@ -77,6 +78,9 @@ void_result committee_member_update_global_parameters_evaluator::do_evaluate(con
{ try {
FC_ASSERT(trx_state->_is_proposed_trx);

FC_ASSERT( db().head_block_time() > HARDFORK_CORE_1468_TIME || !o.new_parameters.extensions.value.updatable_htlc_options.valid(),
"Unable to set HTLC parameters until hardfork." );

return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

Expand Down
1 change: 1 addition & 0 deletions libraries/chain/db_block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ void database::_apply_block( const signed_block& next_block )
clear_expired_transactions();
clear_expired_proposals();
clear_expired_orders();
clear_expired_htlcs();
update_expired_feeds(); // this will update expired feeds and some core exchange rates
update_core_exchange_rates(); // this will update remaining core exchange rates
update_withdraw_permissions();
Expand Down
10 changes: 9 additions & 1 deletion libraries/chain/db_init.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/witness_schedule_object.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/htlc_object.hpp>

#include <graphene/chain/account_evaluator.hpp>
#include <graphene/chain/asset_evaluator.hpp>
Expand All @@ -60,6 +61,7 @@
#include <graphene/chain/withdraw_permission_evaluator.hpp>
#include <graphene/chain/witness_evaluator.hpp>
#include <graphene/chain/worker_evaluator.hpp>
#include <graphene/chain/htlc_evaluator.hpp>

#include <graphene/chain/protocol/fee_schedule.hpp>

Expand Down Expand Up @@ -125,6 +127,9 @@ const uint8_t witness_object::type_id;
const uint8_t worker_object::space_id;
const uint8_t worker_object::type_id;

const uint8_t htlc_object::space_id;
jmjatlanta marked this conversation as resolved.
Show resolved Hide resolved
const uint8_t htlc_object::type_id;


void database::initialize_evaluators()
{
Expand Down Expand Up @@ -173,6 +178,9 @@ void database::initialize_evaluators()
register_evaluator<asset_claim_fees_evaluator>();
register_evaluator<asset_update_issuer_evaluator>();
register_evaluator<asset_claim_pool_evaluator>();
register_evaluator<htlc_create_evaluator>();
register_evaluator<htlc_redeem_evaluator>();
register_evaluator<htlc_extend_evaluator>();
}

void database::initialize_indexes()
Expand Down Expand Up @@ -201,6 +209,7 @@ void database::initialize_indexes()
add_index< primary_index<worker_index> >();
add_index< primary_index<balance_index> >();
add_index< primary_index<blinded_balance_index> >();
add_index< primary_index< htlc_index> >();

//Implementation object indexes
add_index< primary_index<transaction_index > >();
Expand All @@ -216,7 +225,6 @@ void database::initialize_indexes()
add_index< primary_index< special_authority_index > >();
add_index< primary_index< buyback_index > >();
add_index< primary_index<collateral_bid_index > >();

add_index< primary_index< simple_index< fba_accumulator_object > > >();
}

Expand Down
23 changes: 23 additions & 0 deletions libraries/chain/db_notify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <graphene/chain/database.hpp>
#include <graphene/chain/worker_object.hpp>
#include <graphene/chain/confidential_object.hpp>
#include <graphene/chain/htlc_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/committee_member_object.hpp>
#include <graphene/chain/witness_object.hpp>
Expand Down Expand Up @@ -256,6 +257,22 @@ struct get_impacted_account_visitor
{
_impacted.insert( op.fee_payer() ); // account_id
}
void operator()( const htlc_create_operation& op )
{
_impacted.insert( op.fee_payer() );
jmjatlanta marked this conversation as resolved.
Show resolved Hide resolved
}
void operator()( const htlc_redeem_operation& op )
{
_impacted.insert( op.fee_payer() );
jmjatlanta marked this conversation as resolved.
Show resolved Hide resolved
}
void operator()( const htlc_extend_operation& op )
{
_impacted.insert( op.fee_payer() );
}
void operator()( const htlc_refund_operation& op )
{
_impacted.insert( op.fee_payer() );
}
};

void graphene::chain::operation_get_impacted_accounts( const operation& op, flat_set<account_id_type>& result )
Expand Down Expand Up @@ -344,6 +361,12 @@ void get_relevant_accounts( const object* obj, flat_set<account_id_type>& accoun
} case balance_object_type:{
/** these are free from any accounts */
break;
} case htlc_object_type:{
const auto& htlc_obj = dynamic_cast<const htlc_object*>(obj);
FC_ASSERT( htlc_obj != nullptr );
accounts.insert( htlc_obj->from );
accounts.insert( htlc_obj->to );
break;
}
}
}
Expand Down
19 changes: 19 additions & 0 deletions libraries/chain/db_update.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <graphene/chain/asset_object.hpp>
#include <graphene/chain/global_property_object.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/htlc_object.hpp>
#include <graphene/chain/market_object.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/transaction_object.hpp>
Expand Down Expand Up @@ -558,4 +559,22 @@ void database::update_withdraw_permissions()
remove(*permit_index.begin());
}

void database::clear_expired_htlcs()
{
const auto& htlc_idx = get_index_type<htlc_index>().indices().get<by_expiration>();
while ( htlc_idx.begin() != htlc_idx.end()
&& htlc_idx.begin()->expiration <= head_block_time() )
{
const htlc_object& obj = *htlc_idx.begin();
adjust_balance( obj.from, obj.amount );
// virtual op
htlc_refund_operation vop( obj.id, obj.from );
vop.htlc_id = htlc_idx.begin()->id;
push_applied_operation( vop );

// remove the db object
remove( *htlc_idx.begin() );
}
}

} }
4 changes: 4 additions & 0 deletions libraries/chain/hardfork.d/core-1468.hf
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// HTLC implementation
#ifndef HARDFORK_CORE_1468_TIME
#define HARDFORK_CORE_1468_TIME (fc::time_point_sec( 1600000000 ) )
#endif
123 changes: 123 additions & 0 deletions libraries/chain/htlc_evaluator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/*
* Copyright (c) 2018 jmjatlanta and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <graphene/chain/database.hpp>
#include <graphene/chain/htlc_evaluator.hpp>
#include <graphene/chain/htlc_object.hpp>
#include <graphene/chain/hardfork.hpp>

namespace graphene {
namespace chain {

optional<htlc_options> get_committee_htlc_options(graphene::chain::database& db)
{
return db.get_global_properties().parameters.extensions.value.updatable_htlc_options;
}

void_result htlc_create_evaluator::do_evaluate(const htlc_create_operation& o)
{
optional<htlc_options> htlc_options = get_committee_htlc_options(db());

FC_ASSERT(htlc_options, "HTLC Committee options are not set.");

// make sure the expiration is reasonable
FC_ASSERT( o.claim_period_seconds <= htlc_options->max_timeout_secs, "HTLC Timeout exceeds allowed length" );
// make sure the preimage length is reasonable
FC_ASSERT( o.preimage_size <= htlc_options->max_preimage_size, "HTLC preimage length exceeds allowed length" );
// make sure the sender has the funds for the HTLC
FC_ASSERT( db().get_balance( o.from, o.amount.asset_id) >= (o.amount), "Insufficient funds") ;
return void_result();
}

object_id_type htlc_create_evaluator::do_apply(const htlc_create_operation& o)
{
try {
graphene::chain::database& dbase = db();
dbase.adjust_balance( o.from, -o.amount );

const htlc_object& esc = db().create<htlc_object>([&dbase,&o]( htlc_object& esc ) {
esc.from = o.from;
esc.to = o.to;
esc.amount = o.amount;
esc.preimage_hash = o.preimage_hash;
esc.preimage_size = o.preimage_size;
esc.expiration = dbase.head_block_time() + o.claim_period_seconds;
});
return esc.id;

} FC_CAPTURE_AND_RETHROW( (o) )
}

class htlc_redeem_visitor
{
//private:
const std::vector<uint8_t>& data;
public:
typedef bool result_type;

htlc_redeem_visitor( const std::vector<uint8_t>& preimage )
: data( preimage ) {}

template<typename T>
bool operator()( const T& preimage_hash )const
{
return T::hash( (const char*)data.data(), (uint32_t) data.size() ) == preimage_hash;
}
};

void_result htlc_redeem_evaluator::do_evaluate(const htlc_redeem_operation& o)
{
htlc_obj = &db().get<htlc_object>(o.htlc_id);

FC_ASSERT(o.preimage.size() == htlc_obj->preimage_size, "Preimage size mismatch.");

const htlc_redeem_visitor vtor( o.preimage );
FC_ASSERT( htlc_obj->preimage_hash.visit( vtor ), "Provided preimage does not generate correct hash.");

return void_result();
}

void_result htlc_redeem_evaluator::do_apply(const htlc_redeem_operation& o)
{
db().adjust_balance(htlc_obj->to, htlc_obj->amount);
db().remove(*htlc_obj);
return void_result();
}

void_result htlc_extend_evaluator::do_evaluate(const htlc_extend_operation& o)
{
htlc_obj = &db().get<htlc_object>(o.htlc_id);
return void_result();
}

void_result htlc_extend_evaluator::do_apply(const htlc_extend_operation& o)
{
db().modify(*htlc_obj, [&o](htlc_object& db_obj) {
db_obj.expiration += o.seconds_to_add;
});

return void_result();
}

jmjatlanta marked this conversation as resolved.
Show resolved Hide resolved
} // namespace chain
} // namespace graphene
1 change: 1 addition & 0 deletions libraries/chain/include/graphene/chain/database.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -466,6 +466,7 @@ namespace graphene { namespace chain {
void update_withdraw_permissions();
bool check_for_blackswan( const asset_object& mia, bool enable_black_swan = true,
const asset_bitasset_data_object* bitasset_ptr = nullptr );
void clear_expired_htlcs();

///Steps performed only at maintenance intervals
///@{
Expand Down
59 changes: 59 additions & 0 deletions libraries/chain/include/graphene/chain/htlc_evaluator.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2018 jmjatlanta and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once
#include <graphene/chain/evaluator.hpp>

namespace graphene {
namespace chain {

class htlc_create_evaluator : public evaluator<htlc_create_evaluator>
{
public:
typedef htlc_create_operation operation_type;

void_result do_evaluate( const htlc_create_operation& o);
object_id_type do_apply( const htlc_create_operation& o);
};

class htlc_redeem_evaluator : public evaluator<htlc_redeem_evaluator>
{
public:
typedef htlc_redeem_operation operation_type;

void_result do_evaluate( const htlc_redeem_operation& o);
void_result do_apply( const htlc_redeem_operation& o);
const htlc_object* htlc_obj = nullptr;
};

class htlc_extend_evaluator : public evaluator<htlc_extend_evaluator>
{
public:
typedef htlc_extend_operation operation_type;

void_result do_evaluate( const htlc_extend_operation& o);
void_result do_apply( const htlc_extend_operation& o);
const htlc_object* htlc_obj = nullptr;
};
} // namespace graphene
} // namespace graphene
Loading