Added sidechain_proposal_object creation, changed thread_safe_index and input_withdrawal_info

This commit is contained in:
Alexander Suslikov 2019-01-28 11:18:22 +03:00 committed by Anzhy Cherrnyavski
parent df264442da
commit f22d61855b
6 changed files with 91 additions and 37 deletions

View file

@ -30,6 +30,20 @@
namespace graphene { namespace chain {
class sidechain_hardfork_visitor
{
public:
typedef void result_type;
database& db;
sidechain_hardfork_visitor( database& _db ) : db(_db) {}
template<typename T>
void operator()( const T &v, const proposal_id_type prop_id ) const {}
void operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id );
};
class proposal_create_evaluator : public evaluator<proposal_create_evaluator>
{
public:

View file

@ -30,6 +30,7 @@
#include <graphene/chain/protocol/tournament.hpp>
#include <graphene/chain/exceptions.hpp>
#include <graphene/chain/hardfork.hpp>
#include <graphene/chain/sidechain_proposal_object.hpp>
#include <fc/smart_ref_impl.hpp>
@ -142,6 +143,30 @@ struct proposal_operation_hardfork_visitor
}
};
void sidechain_hardfork_visitor::operator()( const bitcoin_transaction_send_operation &v, const proposal_id_type prop_id )
{
db.create<sidechain_proposal_object>([&]( sidechain_proposal_object& sch_prop ) {
sch_prop.proposal_type = sidechain::sidechain_proposal_type::SEND_BTC_TRANSACTION;
sch_prop.proposal_id = prop_id;
});
for( auto& vin : v.vins ) {
auto itr = db.i_w_info.find_info_for_vin( vin.identifier );
if( !itr.first )
continue;
db.i_w_info.mark_as_used_vin( *itr.second );
}
for( auto& vout : v.vouts ) {
auto itr = db.i_w_info.find_info_for_vout( vout );
FC_ASSERT( itr.first, "info_for_vout_object don't exist." );
db.i_w_info.mark_as_used_vout( *itr.second );
}
fc::sha256 hashid = fc::sha256::hash(v.transaction.vin[0].prevout.hash.str() + std::to_string(v.transaction.vin[0].prevout.n));
db.pw_vout_manager.use_latest_vout( hashid );
}
void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
const database& d = db();
@ -157,6 +182,12 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati
FC_ASSERT( !o.review_period_seconds || fc::seconds(*o.review_period_seconds) < (o.expiration_time - d.head_block_time()),
"Proposal review period must be less than its overall lifetime." );
bool pbtc_op = o.proposed_ops[0].op.which() == operation::tag<bitcoin_transaction_send_operation>::value;
if( d.is_sidechain_fork_needed() && pbtc_op ) {
FC_THROW( "Currently the operation is unavailable." );
}
{
// If we're dealing with the committee authority, make sure this transaction has a sufficient review period.
flat_set<account_id_type> auths;
@ -196,6 +227,7 @@ void_result proposal_create_evaluator::do_evaluate(const proposal_create_operati
object_id_type proposal_create_evaluator::do_apply(const proposal_create_operation& o)
{ try {
database& d = db();
sidechain_hardfork_visitor sidechain_vtor( d );
const proposal_object& proposal = d.create<proposal_object>([&](proposal_object& proposal) {
_proposed_trx.expiration = o.expiration_time;
@ -220,6 +252,7 @@ object_id_type proposal_create_evaluator::do_apply(const proposal_create_operati
std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin()));
});
sidechain_vtor( o.proposed_ops[0].op, proposal.id );
return proposal.id;
} FC_CAPTURE_AND_RETHROW( (o) ) }

View file

@ -60,7 +60,7 @@ class input_withdrawal_info
public:
using iterator_id_vin = typename info_for_vin_index::template index<by_id>::type::iterator;
using iterator_identifier_vin = typename info_for_vin_index::template index<by_identifier>::type::iterator;
using iterator_id_vout = typename graphene::chain::info_for_vout_index::index_type::template index<graphene::chain::by_id>::type::iterator;
@ -75,7 +75,7 @@ public:
void remove_info_for_vin( const info_for_vin& obj );
std::pair<bool, input_withdrawal_info::iterator_id_vin> find_info_for_vin( uint64_t id );
std::pair<bool, input_withdrawal_info::iterator_identifier_vin> find_info_for_vin( fc::sha256 identifier );
size_t size_info_for_vins() { return info_for_vins.size(); }
@ -88,7 +88,7 @@ public:
void remove_info_for_vout( const info_for_vout& obj );
std::pair<bool, input_withdrawal_info::iterator_id_vout> find_info_for_vout( uint64_t id );
std::pair<bool, input_withdrawal_info::iterator_id_vout> find_info_for_vout( graphene::chain::info_for_vout_id_type id );
size_t size_info_for_vouts();

View file

@ -4,7 +4,7 @@
namespace sidechain {
struct by_id;
struct by_identifier;
template<class T1>
class thread_safe_index {
@ -12,7 +12,7 @@ class thread_safe_index {
public:
using iterator = typename T1::iterator;
using iterator_id = typename T1::template index<by_id>::type::iterator;
using iterator_identifier = typename T1::template index<by_identifier>::type::iterator;
std::pair<iterator,bool> insert( const typename T1::value_type& value ) {
std::lock_guard<std::recursive_mutex> locker( lock );
@ -34,10 +34,10 @@ public:
return data.size();
}
std::pair<bool, iterator_id> find( uint64_t id ) {
std::pair<bool, iterator_identifier> find( fc::sha256 identifier ) {
std::lock_guard<std::recursive_mutex> locker( lock );
auto& index = data.template get<by_id>();
auto it = index.find( id );
auto& index = data.template get<by_identifier>();
auto it = index.find( identifier );
if( it != index.end() ) {
return std::make_pair(true, it);
}

View file

@ -35,9 +35,9 @@ void input_withdrawal_info::remove_info_for_vin( const info_for_vin& obj )
info_for_vins.remove( obj );
}
std::pair<bool, input_withdrawal_info::iterator_id_vin> input_withdrawal_info::find_info_for_vin( uint64_t id )
std::pair<bool, input_withdrawal_info::iterator_identifier_vin> input_withdrawal_info::find_info_for_vin( fc::sha256 identifier )
{
return info_for_vins.find( id );
return info_for_vins.find( identifier );
}
std::vector<info_for_vin> input_withdrawal_info::get_info_for_vins()
@ -86,10 +86,10 @@ void input_withdrawal_info::remove_info_for_vout( const info_for_vout& obj )
db.remove( obj );
}
std::pair<bool, input_withdrawal_info::iterator_id_vout> input_withdrawal_info::find_info_for_vout( uint64_t id )
std::pair<bool, input_withdrawal_info::iterator_id_vout> input_withdrawal_info::find_info_for_vout( graphene::chain::info_for_vout_id_type id )
{
const auto& info_for_vout_idx = db.get_index_type<graphene::chain::info_for_vout_index>().indices().get< graphene::chain::by_id >();
auto itr = info_for_vout_idx.find( graphene::chain::info_for_vout_id_type( id ) );
auto itr = info_for_vout_idx.find( id );
return std::make_pair( itr != info_for_vout_idx.end(), itr );
}

View file

@ -36,8 +36,9 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_id_test )
for( size_t i = 0; i < 10; i++ ) {
prev_out out = { std::to_string( i ), static_cast<uint32_t>( i ), static_cast< uint64_t >( i ) };
infos.insert_info_for_vin( out, "addr" + std::to_string( i ), { 0x01, 0x02, 0x03 } );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
BOOST_CHECK( infos.find_info_for_vin( identifier ).first );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i );
}
info_for_vin::count_id_info_for_vin = 0;
@ -52,14 +53,15 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_check_data_test )
}
for( size_t i = 0; i < 10; i++ ) {
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.hash_tx == std::to_string( i ) );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.n_vout == i );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.amount == i );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->address == "addr" + std::to_string( i ) );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
BOOST_CHECK( infos.find_info_for_vin( identifier ).first );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.hash_tx == std::to_string( i ) );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.n_vout == i );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.amount == i );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->address == "addr" + std::to_string( i ) );
std::vector<char> script = { 0x01, 0x02, 0x03 };
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->script == script );
}
info_for_vin::count_id_info_for_vin = 0;
@ -75,7 +77,8 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_modify_test )
for( size_t i = 0; i < 10; i++ ) {
if( i % 2 == 0 ) {
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
auto iter = infos.find_info_for_vin( identifier );
BOOST_CHECK( iter.first );
infos.modify_info_for_vin( *iter.second, [&]( info_for_vin& obj ) {
obj.out.hash_tx = std::to_string( i + 1 );
@ -88,14 +91,15 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_modify_test )
for( size_t i = 0; i < 10; i++ ) {
if( i % 2 == 0 ) {
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->id == i );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.hash_tx == std::to_string( i + 1 ) );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.n_vout == i + 1 );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->out.amount == i + 1 );
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->address == "addr" + std::to_string( i ) + std::to_string( i ) );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
BOOST_CHECK( infos.find_info_for_vin( identifier ).first );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->id == i );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.hash_tx == std::to_string( i + 1 ) );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.n_vout == i + 1 );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->out.amount == i + 1 );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->address == "addr" + std::to_string( i ) + std::to_string( i ) );
std::vector<char> script = { 0x01, 0x02, 0x03 };
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).second->script == script );
BOOST_CHECK( infos.find_info_for_vin( identifier ).second->script == script );
}
}
@ -112,17 +116,19 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vin_test )
for( size_t i = 0; i < 10; i++ ) {
if( i % 2 == 0 ) {
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
auto iter = infos.find_info_for_vin( identifier );
BOOST_CHECK( iter.first );
infos.remove_info_for_vin( *iter.second );
}
}
for( size_t i = 0; i < 10; i++ ) {
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
if( i % 2 == 0 ) {
BOOST_CHECK( !infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( !infos.find_info_for_vin( identifier ).first );
} else {
BOOST_CHECK( infos.find_info_for_vin( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( infos.find_info_for_vin( identifier ).first );
}
}
@ -141,7 +147,8 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vins_test )
BOOST_CHECK( vins.size() == 5 ); // 5 amount vins to bitcoin transaction
for( size_t i = 0; i < 7; i++ ) {
auto iter = infos.find_info_for_vin( static_cast< uint64_t >( i ) );
auto identifier = fc::sha256::hash( std::to_string( i ) + std::to_string( i ) );
auto iter = infos.find_info_for_vin( identifier );
infos.mark_as_used_vin( *iter.second );
}
@ -176,7 +183,7 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vout_test )
for( size_t i = 0; i < 10; i++ ) {
if( i % 2 == 0 ) {
auto iter = infos.find_info_for_vout( static_cast< uint64_t >( i ) );
auto iter = infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) );
BOOST_CHECK( iter.first );
infos.remove_info_for_vout( *iter.second );
}
@ -184,9 +191,9 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_remove_vout_test )
for( size_t i = 0; i < 10; i++ ) {
if( i % 2 == 0 ) {
BOOST_CHECK( !infos.find_info_for_vout( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( !infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ).first );
} else {
BOOST_CHECK( infos.find_info_for_vout( static_cast< uint64_t >( i ) ).first );
BOOST_CHECK( infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) ).first );
}
}
}
@ -202,7 +209,7 @@ BOOST_AUTO_TEST_CASE( input_withdrawal_info_get_info_for_vouts_test )
BOOST_CHECK( vouts.size() == 5 ); // 5 amount vouts to bitcoin transaction
for( size_t i = 0; i < 7; i++ ) {
auto iter = infos.find_info_for_vout( static_cast< uint64_t >( i ) );
auto iter = infos.find_info_for_vout( graphene::chain::info_for_vout_id_type(i) );
infos.mark_as_used_vout( *iter.second );
}