Added finalize_bitcoin_transaction, changed bitcoin_transaction_object and bitcoin_transaction_send_operation
This commit is contained in:
parent
0bb271a455
commit
12c5ec3f3f
14 changed files with 115 additions and 23 deletions
|
|
@ -2,6 +2,9 @@
|
|||
#include <graphene/chain/database.hpp>
|
||||
#include <graphene/chain/exceptions.hpp>
|
||||
#include <graphene/chain/bitcoin_transaction_object.hpp>
|
||||
#include <graphene/chain/info_for_used_vin_object.hpp>
|
||||
|
||||
#include <sidechain/sign_bitcoin_transaction.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
|
@ -12,19 +15,34 @@ void_result bitcoin_transaction_send_evaluator::do_evaluate( const bitcoin_trans
|
|||
}
|
||||
|
||||
object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_transaction_send_operation& op )
|
||||
{
|
||||
{
|
||||
bitcoin_transaction_send_operation& mutable_op = const_cast<bitcoin_transaction_send_operation&>( op );
|
||||
database& d = db();
|
||||
std::vector< info_for_used_vin_id_type > new_vins;
|
||||
sidechain::prev_out new_pw_vout = { "", 0, 0 };
|
||||
sidechain::bytes wit_script;
|
||||
|
||||
finalize_bitcoin_transaction( mutable_op );
|
||||
|
||||
for( auto itr : op.vins ){
|
||||
auto itr_id = d.create< info_for_used_vin_object >( [&]( info_for_used_vin_object& obj )
|
||||
{
|
||||
obj.identifier = itr.identifier;
|
||||
obj.out = itr.out;
|
||||
obj.address = itr.address;
|
||||
obj.script = itr.script;
|
||||
}).get_id();
|
||||
new_vins.push_back( itr_id );
|
||||
}
|
||||
|
||||
const bitcoin_transaction_object& btc_tx = d.create< bitcoin_transaction_object >( [&]( bitcoin_transaction_object& obj )
|
||||
{
|
||||
obj.pw_vin = op.pw_vin;
|
||||
obj.vins = op.vins;
|
||||
obj.vouts = op.vouts;
|
||||
obj.transaction = op.transaction;
|
||||
obj.transaction_id = op.transaction.get_txid();
|
||||
obj.fee_for_size = op.fee_for_size;
|
||||
obj.pw_vin = mutable_op.pw_vin;
|
||||
obj.vins = new_vins;
|
||||
obj.vouts = mutable_op.vouts;
|
||||
obj.transaction = mutable_op.transaction;
|
||||
obj.transaction_id = mutable_op.transaction.get_txid();
|
||||
obj.fee_for_size = mutable_op.fee_for_size;
|
||||
obj.confirm = false;
|
||||
});
|
||||
|
||||
|
|
@ -37,6 +55,19 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans
|
|||
return btc_tx.id;
|
||||
}
|
||||
|
||||
void bitcoin_transaction_send_evaluator::finalize_bitcoin_transaction( bitcoin_transaction_send_operation& op )
|
||||
{
|
||||
database& d = db();
|
||||
|
||||
std::vector<std::vector<sidechain::bytes>> new_stacks( sidechain::sort_sigs( op.transaction, op.vins, d.context_verify ) );
|
||||
|
||||
for( size_t i = 0; i < new_stacks.size(); i++ ) {
|
||||
op.transaction.vin[i].scriptWitness = new_stacks[i];
|
||||
}
|
||||
|
||||
sidechain::sign_witness_transaction_finalize( op.transaction, op.vins );
|
||||
}
|
||||
|
||||
void bitcoin_transaction_send_evaluator::send_bitcoin_transaction( const bitcoin_transaction_object& btc_tx )
|
||||
{
|
||||
database& d = db();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@
|
|||
#include <graphene/chain/match_object.hpp>
|
||||
#include <graphene/chain/game_object.hpp>
|
||||
#include <graphene/chain/info_for_vout_object.hpp>
|
||||
#include <graphene/chain/info_for_used_vin_object.hpp>
|
||||
#include <graphene/chain/bitcoin_address_object.hpp>
|
||||
#include <graphene/chain/primary_wallet_vout_object.hpp>
|
||||
#include <graphene/chain/sidechain_proposal_object.hpp>
|
||||
|
|
@ -315,6 +316,7 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<total_distributed_dividend_balance_object_index > >();
|
||||
|
||||
add_index< primary_index<info_for_vout_index > >();
|
||||
add_index< primary_index<info_for_used_vin_index > >();
|
||||
add_index< primary_index<bitcoin_address_index > >();
|
||||
add_index< primary_index<primary_wallet_vout_index > >();
|
||||
add_index< primary_index<sidechain_proposal_index > >();
|
||||
|
|
|
|||
|
|
@ -40,11 +40,17 @@ database::database() :
|
|||
{
|
||||
initialize_indexes();
|
||||
initialize_evaluators();
|
||||
context_sign = secp256k1_context_create(SECP256K1_CONTEXT_SIGN);
|
||||
context_verify = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY);
|
||||
}
|
||||
|
||||
database::~database()
|
||||
{
|
||||
clear_pending();
|
||||
secp256k1_context_destroy(context_sign);
|
||||
context_sign = nullptr;
|
||||
secp256k1_context_destroy(context_verify);
|
||||
context_verify = nullptr;
|
||||
}
|
||||
|
||||
void database::reindex(fc::path data_dir, const genesis_state_type& initial_allocation)
|
||||
|
|
|
|||
|
|
@ -13,6 +13,8 @@ public:
|
|||
|
||||
object_id_type do_apply( const bitcoin_transaction_send_operation& op );
|
||||
|
||||
void finalize_bitcoin_transaction( bitcoin_transaction_send_operation& op );
|
||||
|
||||
void send_bitcoin_transaction( const bitcoin_transaction_object& btc_tx );
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@ class bitcoin_transaction_object : public abstract_object<bitcoin_transaction_ob
|
|||
|
||||
bitcoin_transaction_id_type get_id()const { return id; }
|
||||
|
||||
fc::sha256 pw_vin;
|
||||
fc::optional< fc::sha256 > pw_vin;
|
||||
|
||||
std::vector< fc::sha256 > vins;
|
||||
std::vector< info_for_used_vin_id_type > vins;
|
||||
std::vector< info_for_vout_id_type > vouts;
|
||||
|
||||
sidechain::bitcoin_transaction transaction;
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@
|
|||
#include <fc/log/logger.hpp>
|
||||
|
||||
#include <map>
|
||||
#include <secp256k1.h>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
using graphene::db::abstract_object;
|
||||
|
|
@ -516,6 +517,10 @@ namespace graphene { namespace chain {
|
|||
|
||||
fc::signal<void( const sidechain::bitcoin_transaction& )> send_btc_tx;
|
||||
|
||||
secp256k1_context_t* context_sign;
|
||||
|
||||
secp256k1_context_t* context_verify;
|
||||
|
||||
private:
|
||||
|
||||
vector< processed_transaction > _pending_tx;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,39 @@
|
|||
#pragma once
|
||||
|
||||
#include <graphene/chain/protocol/types.hpp>
|
||||
#include <graphene/db/generic_index.hpp>
|
||||
#include <sidechain/types.hpp>
|
||||
#include <sidechain/bitcoin_address.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
class info_for_used_vin_object : public abstract_object<info_for_used_vin_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = info_for_used_vin_object_type;
|
||||
|
||||
info_for_used_vin_id_type get_id()const { return id; }
|
||||
|
||||
fc::sha256 identifier;
|
||||
|
||||
sidechain::prev_out out;
|
||||
std::string address;
|
||||
sidechain::bytes script;
|
||||
};
|
||||
|
||||
struct by_id;
|
||||
struct by_identifier;
|
||||
|
||||
typedef boost::multi_index_container<
|
||||
info_for_used_vin_object,
|
||||
indexed_by<
|
||||
ordered_unique< tag< by_id >, member< object, object_id_type, &object::id > >,
|
||||
ordered_unique<tag<by_identifier>, member<info_for_used_vin_object, fc::sha256, &info_for_used_vin_object::identifier>>
|
||||
>
|
||||
> info_for_used_vin_multi_index_container;
|
||||
typedef generic_index<info_for_used_vin_object, info_for_used_vin_multi_index_container> info_for_used_vin_index;
|
||||
|
||||
} } // graphene::chain
|
||||
|
||||
FC_REFLECT_DERIVED( graphene::chain::info_for_used_vin_object, (graphene::chain::object), (identifier)(out)(address)(script) )
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <graphene/chain/protocol/base.hpp>
|
||||
#include <sidechain/input_withdrawal_info.hpp>
|
||||
#include <sidechain/bitcoin_transaction.hpp>
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
|
@ -11,16 +12,15 @@ namespace graphene { namespace chain {
|
|||
uint32_t price_per_kbyte = 0;
|
||||
};
|
||||
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
asset fee;
|
||||
account_id_type payer;
|
||||
|
||||
fc::sha256 pw_vin;
|
||||
fc::optional< fc::sha256 > pw_vin;
|
||||
std::vector< sidechain::info_for_vin > vins;
|
||||
std::vector< info_for_vout_id_type > vouts;
|
||||
|
||||
std::vector< fc::sha256 > vins;
|
||||
std::vector< info_for_vout_id_type > vouts;
|
||||
|
||||
sidechain::bitcoin_transaction transaction;
|
||||
uint64_t fee_for_size;
|
||||
sidechain::bitcoin_transaction transaction;
|
||||
uint64_t fee_for_size;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
void validate()const {}
|
||||
|
|
|
|||
|
|
@ -146,6 +146,7 @@ namespace graphene { namespace chain {
|
|||
betting_market_object_type,
|
||||
bet_object_type,
|
||||
info_for_vout_object_type,
|
||||
info_for_used_vin_object_type,
|
||||
bitcoin_address_object_type,
|
||||
primary_wallet_vout_object_type,
|
||||
sidechain_proposal_object_type,
|
||||
|
|
@ -208,6 +209,7 @@ namespace graphene { namespace chain {
|
|||
class betting_market_object;
|
||||
class bet_object;
|
||||
class info_for_vout_object;
|
||||
class info_for_used_vin_object;
|
||||
class bitcoin_address_object;
|
||||
class primary_wallet_vout_object;
|
||||
class sidechain_proposal_object;
|
||||
|
|
@ -239,6 +241,7 @@ namespace graphene { namespace chain {
|
|||
typedef object_id< protocol_ids, betting_market_object_type, betting_market_object> betting_market_id_type;
|
||||
typedef object_id< protocol_ids, bet_object_type, bet_object> bet_id_type;
|
||||
typedef object_id< protocol_ids, info_for_vout_object_type, info_for_vout_object> info_for_vout_id_type;
|
||||
typedef object_id< protocol_ids, info_for_used_vin_object_type, info_for_used_vin_object> info_for_used_vin_id_type;
|
||||
typedef object_id< protocol_ids, bitcoin_address_object_type, bitcoin_address_object> bitcoin_address_id_type;
|
||||
typedef object_id< protocol_ids, primary_wallet_vout_object_type, primary_wallet_vout_object> primary_wallet_vout_id_type;
|
||||
typedef object_id< protocol_ids, sidechain_proposal_object_type, sidechain_proposal_object> sidechain_proposal_id_type;
|
||||
|
|
@ -418,6 +421,7 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
|||
(betting_market_object_type)
|
||||
(bet_object_type)
|
||||
(info_for_vout_object_type)
|
||||
(info_for_used_vin_object_type)
|
||||
(bitcoin_address_object_type)
|
||||
(primary_wallet_vout_object_type)
|
||||
(sidechain_proposal_object_type)
|
||||
|
|
@ -474,6 +478,7 @@ FC_REFLECT_TYPENAME( graphene::chain::betting_market_id_type )
|
|||
FC_REFLECT_TYPENAME( graphene::chain::bet_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::tournament_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::info_for_vout_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::info_for_used_vin_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bitcoin_address_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::primary_wallet_vout_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::sidechain_proposal_id_type )
|
||||
|
|
|
|||
|
|
@ -103,3 +103,5 @@ private:
|
|||
};
|
||||
|
||||
}
|
||||
|
||||
FC_REFLECT( sidechain::info_for_vin, (identifier)(out)(address)(script)(created) )
|
||||
|
|
@ -16,7 +16,7 @@ std::vector<char> privkey_sign( const bytes& privkey, const fc::sha256 &hash, co
|
|||
std::vector< bytes > sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins,
|
||||
const bytes& privkey, const secp256k1_context_t* context_sign = nullptr, int hash_type = 1 );
|
||||
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector< bytes >& redeemScripts );
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins );
|
||||
|
||||
bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const secp256k1_context_t* context );
|
||||
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ std::vector<bytes> sign_witness_transaction_part( const bitcoin_transaction& tx,
|
|||
return signatures;
|
||||
}
|
||||
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<bytes>& redeemScripts )
|
||||
void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector<info_for_vin>& info_vins )
|
||||
{
|
||||
FC_ASSERT( tx.vin.size() == redeemScripts.size() );
|
||||
FC_ASSERT( tx.vin.size() == info_vins.size() );
|
||||
|
||||
for( size_t i = 0; i < tx.vin.size(); i++ ) {
|
||||
tx.vin[i].scriptWitness.insert( tx.vin[i].scriptWitness.begin(), bytes() ); // Bitcoin workaround CHECKMULTISIG bug
|
||||
tx.vin[i].scriptWitness.push_back( redeemScripts[i] );
|
||||
tx.vin[i].scriptWitness.push_back( info_vins[i].script );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ BOOST_AUTO_TEST_CASE( btc_tx_witness_signature_test )
|
|||
secp256k1_context_t* context_sign = secp256k1_context_create( SECP256K1_CONTEXT_SIGN );
|
||||
tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { vin }, privkey_1, context_sign, hash_type)[0] );
|
||||
tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { vin }, privkey_2, context_sign, hash_type)[0] );
|
||||
sign_witness_transaction_finalize( tx, { redeemScript } );
|
||||
sign_witness_transaction_finalize( tx, { vin } );
|
||||
|
||||
BOOST_CHECK( fc::to_hex( pack( tx ) ) == "0100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000" );
|
||||
|
||||
|
|
|
|||
|
|
@ -125,11 +125,11 @@ BOOST_AUTO_TEST_CASE( use_pw_vout_objects )
|
|||
{
|
||||
const auto& idx = db.get_index_type<primary_wallet_vout_index>().indices().get< graphene::chain::by_id >();
|
||||
primary_wallet_vout_manager pw_vout_manager( db );
|
||||
auto itr = idx.begin();
|
||||
|
||||
create_primary_wallet_vouts( pw_vout_manager, db, 1 );
|
||||
pw_vout_manager.use_latest_vout( fc::sha256::hash( "0" + std::to_string( 0 )));
|
||||
|
||||
auto itr = idx.begin();
|
||||
BOOST_CHECK( !pw_vout_manager.get_latest_unused_vout().valid() );
|
||||
BOOST_CHECK( itr->used == true );
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue