Add public key verification mechanism.

This commit is contained in:
Anton Boltach 2019-02-13 14:57:33 +03:00 committed by Anzhy Cherrnyavski
parent b27656d2c9
commit b26e3bc8a1
5 changed files with 111 additions and 4 deletions

View file

@ -154,11 +154,12 @@ void database::processing_sidechain_proposals( const witness_object& current_wit
case sidechain_proposal_type::ISSUE_BTC :{
approve_propose( proposal->id );
break;
}
}
case sidechain_proposal_type::SEND_BTC_TRANSACTION :{
bitcoin_transaction_send_operation op = proposal->proposed_transaction.operations.back().get<bitcoin_transaction_send_operation>();
if( checker.check_bitcoin_transaction_send_operation( op ) && checker.check_witness_opportunity_to_approve( current_witness, *proposal ) )
{
if( checker.check_bitcoin_transaction_send_operation( op ) &&
checker.check_witnesses_keys( current_witness, *proposal ) &&
checker.check_witness_opportunity_to_approve( current_witness, *proposal ) ) {
const auto& sign_operation = create_sign_btc_tx_operation( current_witness, private_key, proposal->id );
_pending_tx.insert( _pending_tx.begin(), create_signed_transaction( private_key, sign_operation ) );
}

View file

@ -530,7 +530,7 @@ namespace graphene { namespace chain {
int64_t get_estimated_fee( size_t tx_vsize, uint64_t estimated_feerate );
void processing_sidechain_proposals( const witness_object& current_witness, const private_key& signing_private_key );
sidechain::full_btc_transaction create_btc_transaction( const std::vector<info_for_vin>& info_vins,
const std::vector<info_for_vout>& info_vouts,
const info_for_vin& info_pw_vin );

View file

@ -21,6 +21,8 @@ public:
bool check_witness_opportunity_to_approve( const witness_object& current_witness, const proposal_object& proposal );
bool check_witnesses_keys( const witness_object& current_witness, const proposal_object& proposal );
bool check_bitcoin_transaction_revert_operation( const bitcoin_transaction_revert_operation& op );
private:

View file

@ -169,6 +169,32 @@ bool sidechain_proposal_checker::check_witness_opportunity_to_approve( const wit
return is_active_witness() && does_the_witness_have_authority();
}
bool sidechain_proposal_checker::check_witnesses_keys( const witness_object& current_witness, const proposal_object& proposal )
{
bitcoin_transaction_send_operation op = proposal.proposed_transaction.operations.back().get<bitcoin_transaction_send_operation>();
auto vins = op.vins;
if( op.pw_vin.identifier.str().compare( 0, 48, SIDECHAIN_NULL_VIN_IDENTIFIER ) != 0 ) {
vins.insert( vins.begin(), op.pw_vin );
}
const auto& bitcoin_address_idx = db.get_index_type<bitcoin_address_index>().indices().get< by_address >();
for ( const auto& info_vins : vins ) {
const auto& address_itr = bitcoin_address_idx.find( info_vins.address );
if ( address_itr != bitcoin_address_idx.end() ) {
const auto& witness_key = current_witness.signing_key;
const auto& witnesses_keys = address_itr->address.witnesses_keys;
const auto& witnesses_keys_itr = witnesses_keys.find( current_witness.witness_account );
if ( witnesses_keys_itr == witnesses_keys.end() || witnesses_keys_itr->second != witness_key ) {
return false;
}
}
}
return true;
}
bool sidechain_proposal_checker::check_bitcoin_transaction_revert_operation( const bitcoin_transaction_revert_operation& op )
{
const auto& btc_trx_idx = db.get_index_type<bitcoin_transaction_index>().indices().get<by_transaction_id>();

View file

@ -5,6 +5,7 @@
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/proposal_evaluator.hpp>
#include <graphene/chain/witness_object.hpp>
#include <graphene/chain/bitcoin_address_object.hpp>
#include <graphene/chain/bitcoin_transaction_object.hpp>
using namespace sidechain;
@ -245,6 +246,83 @@ BOOST_AUTO_TEST_CASE( not_account_auths_wit_try_to_approve_btc_send_test )
BOOST_CHECK( !checker.check_witness_opportunity_to_approve( *itr, *proposal_idx.begin() ) );
}
BOOST_AUTO_TEST_CASE ( check_witness_keys_test_normal )
{
sidechain_proposal_checker checker( db );
auto witnesses_keys = db.get_latest_PW().address.witnesses_keys;
const auto& bitcoin_address = db.create<bitcoin_address_object>( [&]( bitcoin_address_object& obj ) {
witnesses_keys.erase( ++witnesses_keys.begin() );
obj.address = sidechain::btc_multisig_segwit_address( SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG, witnesses_keys );
obj.owner = account_id_type( 13 );
} );
info_for_vin vin;
vin.address = bitcoin_address.address.address;
bitcoin_transaction_send_operation op;
op.vins = { vin };
proposal_object proposal;
proposal.proposed_transaction.operations.push_back( op );
const witness_id_type& witness_id = *db.get_global_properties().active_witnesses.begin();
const witness_object witness = witness_id( db );
BOOST_CHECK( checker.check_witnesses_keys( witness, proposal ) );
}
BOOST_AUTO_TEST_CASE ( check_witnesses_keys_incorrect_witness_test )
{
sidechain_proposal_checker checker( db );
auto witnesses_keys = db.get_latest_PW().address.witnesses_keys;
const auto& bitcoin_address = db.create<bitcoin_address_object>( [&]( bitcoin_address_object& obj ) {
witnesses_keys.erase( ++witnesses_keys.begin() );
obj.address = sidechain::btc_multisig_segwit_address( SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG, witnesses_keys );
obj.owner = account_id_type( 13 );
} );
info_for_vin vin;
vin.address = bitcoin_address.address.address;
bitcoin_transaction_send_operation op;
op.vins = { vin };
proposal_object proposal;
proposal.proposed_transaction.operations.push_back( op );
const witness_object witness;
BOOST_CHECK( !checker.check_witnesses_keys( witness, proposal ) );
}
BOOST_AUTO_TEST_CASE ( check_witnesses_keys_nonexistent_witness_test )
{
sidechain_proposal_checker checker( db );
auto witnesses_keys = db.get_latest_PW().address.witnesses_keys;
const auto& bitcoin_address = db.create<bitcoin_address_object>( [&]( bitcoin_address_object& obj ) {
witnesses_keys.erase( ++witnesses_keys.begin() );
obj.address = sidechain::btc_multisig_segwit_address( SIDECHAIN_DEFAULT_NUMBER_SIG_MULTISIG, witnesses_keys );
obj.owner = account_id_type( 13 );
} );
info_for_vin vin;
vin.address = bitcoin_address.address.address;
bitcoin_transaction_send_operation op;
op.vins = { vin };
proposal_object proposal;
proposal.proposed_transaction.operations.push_back( op );
const witness_id_type& witness_id = *++db.get_global_properties().active_witnesses.begin();
const witness_object witness = witness_id( db );
BOOST_CHECK( !checker.check_witnesses_keys( witness, proposal ) );
}
void create_missing_bto( graphene::chain::database& db, uint32_t amount )
{
BOOST_REQUIRE( amount < 9 );