revert to combination of signing and approval
This commit is contained in:
parent
ed19ccee25
commit
f2a38419ce
6 changed files with 85 additions and 62 deletions
|
|
@ -28,7 +28,7 @@ namespace graphene { namespace chain {
|
|||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
bitcoin_transaction_id_type tx_id;
|
||||
proposal_id_type proposal_id;
|
||||
std::vector<peerplays_sidechain::bytes> signatures;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
|
|
@ -56,7 +56,7 @@ FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation::fee_parameters_
|
|||
FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation, (fee)(payer)(unsigned_tx)(redeem_script)(in_amounts)(signatures) )
|
||||
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(tx_id)(signatures) )
|
||||
FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) )
|
||||
|
||||
FC_REFLECT( graphene::chain::bitcoin_send_transaction_process_operation::fee_parameters_type, (fee) )
|
||||
FC_REFLECT( graphene::chain::bitcoin_send_transaction_process_operation, (fee)(payer)(bitcoin_transaction_id) )
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ public:
|
|||
|
||||
void_result do_evaluate(const bitcoin_transaction_sign_operation& o);
|
||||
object_id_type do_apply(const bitcoin_transaction_sign_operation& o);
|
||||
void update_proposal(const bitcoin_transaction_sign_operation& o);
|
||||
};
|
||||
|
||||
class bitcoin_send_transaction_process_evaluator : public evaluator<bitcoin_send_transaction_process_evaluator>
|
||||
|
|
|
|||
|
|
@ -43,26 +43,24 @@ void_result bitcoin_transaction_sign_evaluator::do_evaluate(const bitcoin_transa
|
|||
try
|
||||
{
|
||||
FC_ASSERT(db().head_block_time() >= HARDFORK_SON_TIME, "Not allowed until SON HARDFORK"); // can be removed after HF date pass
|
||||
const auto &tx_idx = db().get_index_type<bitcoin_transaction_index>().indices().get<by_id>();
|
||||
const auto &tx_itr = tx_idx.find(op.tx_id);
|
||||
FC_ASSERT(tx_idx.end() != tx_itr, "bitcoin transaction not found");
|
||||
const auto &proposal_idx = db().get_index_type<proposal_index>().indices().get<by_id>();
|
||||
const auto &proposal_itr = proposal_idx.find(op.proposal_id);
|
||||
FC_ASSERT(proposal_idx.end() != proposal_itr, "proposal not found");
|
||||
// Checks can this SON approve this proposal
|
||||
const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||
auto son_obj = sidx.find(op.payer);
|
||||
FC_ASSERT(son_obj != sidx.end(), "Unknown SON as payer");
|
||||
// Get bitcoin tx from proposal
|
||||
FC_ASSERT(proposal_itr->proposed_transaction.operations.size() == 1, "Invalid proposal");
|
||||
auto op = proposal_itr->proposed_transaction.operations[0];
|
||||
FC_ASSERT(op.which() == chain::operation::tag<chain::bitcoin_transaction_send_operation>::value, "Invalid proposal");
|
||||
bitcoin_transaction_send_operation btx_op = op.get<bitcoin_transaction_send_operation>();
|
||||
// Find the SON among the tx signers
|
||||
auto it = btx_op.signatures.find(son_obj->id);
|
||||
FC_ASSERT(it != btx_op.signatures.end(), "SON is not tx signer");
|
||||
// tx is not signed with this son already
|
||||
FC_ASSERT(it->second.empty(), "This SON has already signed this tx");
|
||||
|
||||
// Checks can this SON sign this tx
|
||||
auto can_this_son_sign_this_tx = [&]() {
|
||||
const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||
auto son_obj = sidx.find(op.payer);
|
||||
if (son_obj == sidx.end())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto it = tx_itr->signatures.find(son_obj->id);
|
||||
if (it == tx_itr->signatures.end())
|
||||
return false;
|
||||
// tx is not signed with this son already
|
||||
return it->second.empty();
|
||||
};
|
||||
|
||||
FC_ASSERT(can_this_son_sign_this_tx(), "Invalid approval received");
|
||||
return void_result();
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW((op))
|
||||
|
|
@ -72,23 +70,45 @@ object_id_type bitcoin_transaction_sign_evaluator::do_apply(const bitcoin_transa
|
|||
{
|
||||
try
|
||||
{
|
||||
const auto &bitcoin_tx = op.tx_id(db());
|
||||
const auto &proposal = op.proposal_id(db());
|
||||
const auto &sidx = db().get_index_type<son_index>().indices().get<graphene::chain::by_account>();
|
||||
auto son_obj = sidx.find(op.payer);
|
||||
|
||||
db().modify(bitcoin_tx, [&](bitcoin_transaction_object &btx) {
|
||||
btx.signatures[son_obj->id] = op.signatures;
|
||||
db().modify(proposal, [&](proposal_object &po) {
|
||||
auto bitcoin_transaction_send_op = po.proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||
bitcoin_transaction_send_op.signatures[son_obj->id] = op.signatures;
|
||||
po.proposed_transaction.operations[0] = bitcoin_transaction_send_op;
|
||||
});
|
||||
|
||||
db().modify( son_obj->statistics( db() ), [&]( son_statistics_object& sso ) {
|
||||
sso.txs_signed += 1;
|
||||
} );
|
||||
|
||||
return bitcoin_tx.id;
|
||||
update_proposal(op);
|
||||
return op.proposal_id;
|
||||
}
|
||||
FC_CAPTURE_AND_RETHROW((op))
|
||||
}
|
||||
|
||||
void bitcoin_transaction_sign_evaluator::update_proposal(const bitcoin_transaction_sign_operation &op)
|
||||
{
|
||||
database &d = db();
|
||||
proposal_update_operation update_op;
|
||||
|
||||
update_op.fee_paying_account = op.payer;
|
||||
update_op.proposal = op.proposal_id;
|
||||
update_op.active_approvals_to_add = {op.payer};
|
||||
|
||||
bool skip_fee_old = trx_state->skip_fee;
|
||||
bool skip_fee_schedule_check_old = trx_state->skip_fee_schedule_check;
|
||||
trx_state->skip_fee = true;
|
||||
trx_state->skip_fee_schedule_check = true;
|
||||
|
||||
d.apply_operation(*trx_state, update_op);
|
||||
|
||||
trx_state->skip_fee = skip_fee_old;
|
||||
trx_state->skip_fee_schedule_check = skip_fee_schedule_check_old;
|
||||
}
|
||||
|
||||
void_result bitcoin_send_transaction_process_evaluator::do_evaluate(const bitcoin_send_transaction_process_operation &op)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -445,11 +445,6 @@ void peerplays_sidechain_plugin_impl::approve_proposals() {
|
|||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::bitcoin_transaction_send_operation>::value) {
|
||||
approve_proposal(son_id, proposal.id);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (proposal.proposed_transaction.operations.size() == 1 && proposal.proposed_transaction.operations[0].which() == chain::operation::tag<chain::bitcoin_send_transaction_process_operation>::value) {
|
||||
approve_proposal(son_id, proposal.id);
|
||||
continue;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include <graphene/chain/account_object.hpp>
|
||||
#include <graphene/chain/protocol/son_wallet.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/sidechain_address_object.hpp>
|
||||
#include <graphene/chain/sidechain_transaction_object.hpp>
|
||||
#include <graphene/chain/son_info.hpp>
|
||||
|
|
@ -681,38 +682,44 @@ static bool has_enough_signatures(const bitcoin_transaction_object &tx_object) {
|
|||
return !has_empty;
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::process_signing() {
|
||||
const auto &idx = plugin.database().get_index_type<bitcoin_transaction_index>().indices().get<by_processed>();
|
||||
const auto &idx_range = idx.equal_range(false);
|
||||
std::for_each(idx_range.first, idx_range.second,
|
||||
[&](const bitcoin_transaction_object &tx_object) {
|
||||
// collect signatures
|
||||
auto sons = plugin.get_sons();
|
||||
for (son_id_type son_id : sons) {
|
||||
auto it = tx_object.signatures.find(son_id);
|
||||
if (it == tx_object.signatures.end())
|
||||
continue;
|
||||
if (it->second.empty())
|
||||
{
|
||||
bitcoin_transaction_sign_operation op;
|
||||
son_object s_obj= plugin.get_son_object(son_id);
|
||||
op.payer = s_obj.son_account;
|
||||
op.tx_id = tx_object.id;
|
||||
fc::ecc::private_key k = plugin.get_private_key(son_id);
|
||||
op.signatures = signatures_for_raw_transaction(tx_object.unsigned_tx, tx_object.in_amounts, tx_object.redeem_script, k);
|
||||
void sidechain_net_handler_bitcoin::process_signing()
|
||||
{
|
||||
const auto &idx = plugin.database().get_index_type<proposal_index>().indices().get<by_id>();
|
||||
vector<proposal_id_type> proposals;
|
||||
for (const auto &proposal : idx) {
|
||||
if (proposal.proposed_transaction.operations.size() != 1)
|
||||
continue;
|
||||
if (proposal.proposed_transaction.operations[0].which() != chain::operation::tag<chain::bitcoin_transaction_send_operation>::value) {
|
||||
continue;
|
||||
}
|
||||
bitcoin_transaction_send_operation tx_object = proposal.proposed_transaction.operations[0].get<bitcoin_transaction_send_operation>();
|
||||
// collect signatures
|
||||
auto sons = plugin.get_sons();
|
||||
for (son_id_type son_id : sons) {
|
||||
auto it = tx_object.signatures.find(son_id);
|
||||
if (it == tx_object.signatures.end())
|
||||
continue;
|
||||
if (it->second.empty())
|
||||
{
|
||||
bitcoin_transaction_sign_operation op;
|
||||
son_object s_obj= plugin.get_son_object(son_id);
|
||||
op.payer = s_obj.son_account;
|
||||
op.proposal_id = proposal.id;
|
||||
fc::ecc::private_key k = plugin.get_private_key(son_id);
|
||||
op.signatures = signatures_for_raw_transaction(tx_object.unsigned_tx, tx_object.in_amounts, tx_object.redeem_script, k);
|
||||
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(k, op);
|
||||
try {
|
||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: bitcoin transaction signing failed with exception ${e}",("e", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
signed_transaction trx = plugin.database().create_signed_transaction(k, op);
|
||||
try {
|
||||
plugin.database().push_transaction(trx, database::validation_steps::skip_block_size_check);
|
||||
if(plugin.app().p2p_node())
|
||||
plugin.app().p2p_node()->broadcast(net::trx_message(trx));
|
||||
} catch(fc::exception e){
|
||||
ilog("sidechain_net_handler: bitcoin transaction signing failed with exception ${e}",("e", e.what()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sidechain_net_handler_bitcoin::complete_signing()
|
||||
|
|
|
|||
|
|
@ -231,7 +231,7 @@ BOOST_AUTO_TEST_CASE(bitcoin_transaction_send_test)
|
|||
bitcoin_transaction_sign_operation sign_op;
|
||||
|
||||
sign_op.payer = alice_id;
|
||||
//sign_op.proposal_id = proposal_id_type(0);
|
||||
sign_op.proposal_id = proposal_id_type(0);
|
||||
sign_op.signatures.push_back(a1);
|
||||
sign_op.signatures.push_back(a2);
|
||||
sign_op.signatures.push_back(a3);
|
||||
|
|
|
|||
Loading…
Reference in a new issue