From 810051e7c95ecd0f60b010fbe13fa8f665ec999d Mon Sep 17 00:00:00 2001 From: Anzhy Cherrnyavski Date: Thu, 31 Jan 2019 14:50:31 +0300 Subject: [PATCH] Signature bitcoin transaction and confirmation proposal --- .../chain/bitcoin_transaction_evaluator.cpp | 45 ++++-- libraries/chain/db_block.cpp | 4 + libraries/chain/db_sidechain.cpp | 48 ++++++- .../chain/include/graphene/chain/database.hpp | 13 +- .../chain/protocol/bitcoin_transaction.hpp | 4 +- .../sidechain/input_withdrawal_info.hpp | 7 + .../sidechain/sign_bitcoin_transaction.hpp | 11 +- .../sidechain/include/sidechain/types.hpp | 3 +- libraries/sidechain/input_withdrawal_info.cpp | 20 +++ .../network/sidechain_net_manager.cpp | 1 - .../sidechain/sign_bitcoin_transaction.cpp | 26 ++-- tests/tests/bitcoin_sign_tests.cpp | 136 +++++++++++------- 12 files changed, 217 insertions(+), 101 deletions(-) diff --git a/libraries/chain/bitcoin_transaction_evaluator.cpp b/libraries/chain/bitcoin_transaction_evaluator.cpp index 0b2d8ec6..f63b96e9 100644 --- a/libraries/chain/bitcoin_transaction_evaluator.cpp +++ b/libraries/chain/bitcoin_transaction_evaluator.cpp @@ -9,7 +9,8 @@ #include #include - +#include +#include namespace graphene { namespace chain { @@ -25,7 +26,6 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans { bitcoin_transaction_send_operation& mutable_op = const_cast( op ); database& d = db(); - sidechain::bytes wit_script; finalize_bitcoin_transaction( mutable_op ); @@ -43,6 +43,7 @@ object_id_type bitcoin_transaction_send_evaluator::do_apply( const bitcoin_trans }); sidechain::prev_out new_pw_vout = { "", 0, 0 }; + sidechain::bytes wit_script = d.get_latest_PW().address.get_witness_script(); if( btc_tx.transaction.vout[0].is_p2wsh() && btc_tx.transaction.vout[0].scriptPubKey == wit_script ) new_pw_vout = { btc_tx.transaction.get_txid(), 0, btc_tx.transaction.vout[0].value }; @@ -71,19 +72,34 @@ std::vector< info_for_used_vin_id_type > bitcoin_transaction_send_evaluator::cre if( obj_itr.valid() ) d.i_w_info.remove_info_for_vin( *obj_itr ); } + + return new_vins; } void bitcoin_transaction_send_evaluator::finalize_bitcoin_transaction( bitcoin_transaction_send_operation& op ) { database& d = db(); - std::vector> new_stacks( sidechain::sort_sigs( op.transaction, op.vins, d.context_verify ) ); + auto vins = op.vins; + if( op.pw_vin.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) != 0 ) { + const auto& pw_vout = d.pw_vout_manager.get_vout( op.pw_vin ); + info_for_vin vin; + vin.out = pw_vout->vout; + vin.address = d.get_latest_PW().address.get_address(); + vin.identifier = pw_vout->hash_id; + vins.insert( vins.begin(), vin ); + } + + std::vector redeem_scripts( d.i_w_info.get_redeem_scripts( vins ) ); + std::vector amounts( d.i_w_info.get_amounts( vins ) ); + + std::vector> new_stacks( sidechain::sort_sigs( op.transaction, redeem_scripts, amounts, 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 ); + sidechain::sign_witness_transaction_finalize( op.transaction, redeem_scripts ); } void bitcoin_transaction_send_evaluator::send_bitcoin_transaction( const bitcoin_transaction_object& btc_tx ) @@ -99,18 +115,16 @@ void_result bitcoin_transaction_sign_evaluator::do_evaluate( const bitcoin_trans { database& d = db(); - const auto& sidechain_proposal_idx = d.get_index_type().indices().get(); - const auto& sidechain_proposal_itr = sidechain_proposal_idx.find( op.sidechain_proposal_id ); - FC_ASSERT( sidechain_proposal_idx.end() != sidechain_proposal_itr, - "sidechain_proposal not found"); + const auto& proposal_idx = d.get_index_type().indices().get(); + const auto& proposal_itr = proposal_idx.find( op.proposal_id ); + FC_ASSERT( proposal_idx.end() != proposal_itr, "proposal not found"); witness_id_type scheduled_witness = d.get_scheduled_witness( 1 ); const auto& witness_obj = d.get< witness_object >( scheduled_witness ); FC_ASSERT( witness_obj.witness_account == op.payer, "Incorrect witness." ); sidechain::bytes public_key( public_key_data_to_bytes( witness_obj.signing_key.key_data ) ); - const auto& proposal = sidechain_proposal_itr->proposal_id( d ); - auto btc_send_op = proposal.proposed_transaction.operations[0].get(); + auto btc_send_op = proposal_itr->proposed_transaction.operations[0].get(); FC_ASSERT( check_sigs( public_key, op.signatures, btc_send_op.vins, btc_send_op.transaction ) ); // Add pw_vin // const auto& proposal = sidechain_proposal_itr->proposal_id( d ); @@ -122,9 +136,7 @@ void_result bitcoin_transaction_sign_evaluator::do_evaluate( const bitcoin_trans void_result bitcoin_transaction_sign_evaluator::do_apply( const bitcoin_transaction_sign_operation& op ) { database& d = db(); - - const auto& sidechain_proposal = op.sidechain_proposal_id( d ); - const auto& proposal = sidechain_proposal.proposal_id( d ); + const auto& proposal = op.proposal_id( d ); d.modify( proposal, [&]( proposal_object& po ) { auto bitcoin_transaction_send_op = po.proposed_transaction.operations[0].get(); @@ -145,7 +157,7 @@ void bitcoin_transaction_sign_evaluator::update_proposal( const bitcoin_transact proposal_update_operation update_op; update_op.fee_paying_account = op.payer; - update_op.proposal = op.sidechain_proposal_id( d ).proposal_id; + update_op.proposal = op.proposal_id; update_op.active_approvals_to_add = { op.payer }; bool skip_fee_old = trx_state->skip_fee; @@ -164,9 +176,12 @@ bool bitcoin_transaction_sign_evaluator::check_sigs( const bytes& key_data, cons const bitcoin_transaction& tx ) { FC_ASSERT( sigs.size() == info_for_vins.size() && sigs.size() == tx.vin.size() ); + const auto& bitcoin_address_idx = db().get_index_type().indices().get< by_address >(); for( size_t i = 0; i < tx.vin.size(); i++ ) { - const bytes& script = info_for_vins[i].script; + const auto pbtc_address = bitcoin_address_idx.find( info_for_vins[i].address ); + const bytes& script = pbtc_address->address.get_redeem_script(); + const auto& sighash_str = get_signature_hash( tx, script, static_cast( info_for_vins[i].out.amount ), i, 1, true ).str(); const bytes& sighash_hex = parse_hex( sighash_str ); diff --git a/libraries/chain/db_block.cpp b/libraries/chain/db_block.cpp index d7ea2180..e84b3da2 100644 --- a/libraries/chain/db_block.cpp +++ b/libraries/chain/db_block.cpp @@ -394,6 +394,10 @@ signed_block database::_generate_block( auto maximum_block_size = get_global_properties().parameters.maximum_block_size; size_t total_block_size = max_block_header_size; + if( !is_sidechain_fork_needed() ) { + processing_sidechain_proposals( witness_obj, block_signing_private_key ); + } + signed_block pending_block; // diff --git a/libraries/chain/db_sidechain.cpp b/libraries/chain/db_sidechain.cpp index 4ce17bef..57f027c2 100644 --- a/libraries/chain/db_sidechain.cpp +++ b/libraries/chain/db_sidechain.cpp @@ -4,6 +4,7 @@ #include #include #include +#include using namespace sidechain; @@ -133,8 +134,11 @@ void database::processing_sidechain_proposals( const witness_object& current_wit switch( sidechain_proposal.proposal_type ) { case sidechain_proposal_type::ISSUE_PBTC :{} - case sidechain_proposal_type::SEND_BTC_TRANSACTION :{} - case sidechain_proposal_type::WITHDRAW_PBTC :{} + case sidechain_proposal_type::SEND_BTC_TRANSACTION :{ + 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 ) ); + break; + } case sidechain_proposal_type::RETURN_PBTC_BACK :{} } } @@ -142,12 +146,13 @@ void database::processing_sidechain_proposals( const witness_object& current_wit full_btc_transaction database::create_btc_transaction( const std::vector& info_vins, const std::vector& info_vouts, - const fc::optional& info_pw_vin ) + const info_for_vin& info_pw_vin ) { sidechain_condensing_tx ctx( info_vins, info_vouts ); - if( info_pw_vin->identifier.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) == 0 ) { - ctx.create_pw_vin( *info_pw_vin ); + + if( info_pw_vin.identifier.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) == 0 ) { + ctx.create_pw_vin( info_pw_vin ); } const auto& pw_address = get_latest_PW().address; @@ -173,7 +178,7 @@ fc::optional database::create_send_btc_tx_proposal( const witness_obj const auto& info_pw_vin = i_w_info.get_info_for_pw_vin(); if( info_pw_vin.valid() && ( info_vins.size() || info_vouts.size() ) ) { - const auto& btc_tx_and_size_fee = create_btc_transaction( info_vins, info_vouts, info_pw_vin ); + const auto& btc_tx_and_size_fee = create_btc_transaction( info_vins, info_vouts, *info_pw_vin ); bitcoin_transaction_send_operation btc_send_op; btc_send_op.payer = get_sidechain_account_id(); @@ -209,6 +214,37 @@ signed_transaction database::create_signed_transaction( const private_key& signi return processed_trx; } +operation database::create_sign_btc_tx_operation( const witness_object& current_witness, const private_key_type& privkey, + const proposal_id_type& proposal_id ) +{ + const auto& proposal_idx = get_index_type().indices().get(); + const auto& proposal_itr = proposal_idx.find( proposal_id ); + bitcoin_transaction_send_operation op = proposal_itr->proposed_transaction.operations.back().get(); + + bitcoin_transaction_sign_operation sign_operation; + sign_operation.payer = current_witness.witness_account; + sign_operation.proposal_id = proposal_id; + const auto secret = privkey.get_secret(); + bytes key(secret.data(), secret.data() + secret.data_size()); + + auto vins = op.vins; + if( op.pw_vin.str().compare( 0, 24, SIDECHAIN_NULL_VIN_IDENTIFIER ) != 0 ) { + const auto& pw_vout = pw_vout_manager.get_vout( op.pw_vin ); + info_for_vin vin; + vin.out = pw_vout->vout; + vin.address = get_latest_PW().address.get_address(); + vin.identifier = pw_vout->hash_id; + vins.insert( vins.begin(), vin ); + } + + std::vector redeem_scripts( i_w_info.get_redeem_scripts( vins ) ); + std::vector amounts( i_w_info.get_amounts( vins ) ); + + sign_operation.signatures = sign_witness_transaction_part( op.transaction, redeem_scripts, amounts, key, context_sign, 1 ); + + return sign_operation; +} + void database::remove_sidechain_proposal_object( const proposal_object& proposal ) { try { if( proposal.proposed_transaction.operations.size() == 1 && diff --git a/libraries/chain/include/graphene/chain/database.hpp b/libraries/chain/include/graphene/chain/database.hpp index da819fee..387d7fe6 100644 --- a/libraries/chain/include/graphene/chain/database.hpp +++ b/libraries/chain/include/graphene/chain/database.hpp @@ -51,6 +51,9 @@ #include using namespace fc::ecc; +using sidechain::bitcoin_transaction; +using sidechain::info_for_vin; +using sidechain::info_for_vout; namespace graphene { namespace chain { using graphene::db::abstract_object; @@ -528,10 +531,12 @@ namespace graphene { namespace chain { 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_vins, - const std::vector& info_vouts, - const fc::optional& info_pw_vin ); + sidechain::full_btc_transaction create_btc_transaction( const std::vector& info_vins, + const std::vector& info_vouts, + const info_for_vin& info_pw_vin ); fc::optional create_send_btc_tx_proposal( const witness_object& current_witness ); + operation create_sign_btc_tx_operation( const witness_object& current_witness, const private_key_type& privkey, + const proposal_id_type& proposal_id ); signed_transaction create_signed_transaction( const private_key& signing_private_key, const operation& op ); void remove_sidechain_proposal_object( const proposal_object& proposal ); @@ -539,7 +544,7 @@ namespace graphene { namespace chain { void roll_back_vin_and_vout( const proposal_object& proposal ); - fc::signal send_btc_tx; + fc::signal send_btc_tx; sidechain::input_withdrawal_info i_w_info; diff --git a/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp b/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp index a4c4b3b1..5ccba200 100644 --- a/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp +++ b/libraries/chain/include/graphene/chain/protocol/bitcoin_transaction.hpp @@ -41,7 +41,7 @@ namespace graphene { namespace chain { asset fee; account_id_type payer; - sidechain_proposal_id_type sidechain_proposal_id; + proposal_id_type proposal_id; std::vector signatures; account_id_type fee_payer()const { return payer; } @@ -55,4 +55,4 @@ FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation::fee_parameters_ FC_REFLECT( graphene::chain::bitcoin_transaction_send_operation, (fee)(payer)(vins)(vouts)(transaction)(fee_for_size) ) FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation::fee_parameters_type, (fee)(price_per_kbyte) ) -FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(sidechain_proposal_id)(signatures) ) +FC_REFLECT( graphene::chain::bitcoin_transaction_sign_operation, (fee)(payer)(proposal_id)(signatures) ) diff --git a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp index f9565a99..6a62fa60 100644 --- a/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp +++ b/libraries/sidechain/include/sidechain/input_withdrawal_info.hpp @@ -61,8 +61,15 @@ class input_withdrawal_info public: input_withdrawal_info( graphene::chain::database& _db ) : db( _db ) {} + + std::vector get_redeem_scripts( const std::vector& info_vins ); + + std::vector get_amounts( const std::vector& info_vins ); + + fc::optional get_info_for_pw_vin(); + void insert_info_for_vin( const prev_out& out, const std::string& address, bytes script = bytes() ); void modify_info_for_vin( const info_for_vin& obj, const std::function& func ); diff --git a/libraries/sidechain/include/sidechain/sign_bitcoin_transaction.hpp b/libraries/sidechain/include/sidechain/sign_bitcoin_transaction.hpp index 11b6e4c4..6c2ade49 100644 --- a/libraries/sidechain/include/sidechain/sign_bitcoin_transaction.hpp +++ b/libraries/sidechain/include/sidechain/sign_bitcoin_transaction.hpp @@ -13,14 +13,15 @@ fc::sha256 get_signature_hash( const bitcoin_transaction& tx, const bytes& scrip std::vector privkey_sign( const bytes& privkey, const fc::sha256 &hash, const secp256k1_context_t* context_sign = nullptr ); -std::vector< bytes > sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector& info_vins, - const bytes& privkey, const secp256k1_context_t* context_sign = nullptr, int hash_type = 1 ); +std::vector sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector& redeem_scripts, + const std::vector& amounts, 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& info_vins ); +void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector& redeem_scripts ); bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const secp256k1_context_t* context ); -std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector& info_vins, - const secp256k1_context_t* context ); +std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector& redeem_scripts, + const std::vector& amounts, const secp256k1_context_t* context ); } diff --git a/libraries/sidechain/include/sidechain/types.hpp b/libraries/sidechain/include/sidechain/types.hpp index 35ad8004..d3b3312b 100644 --- a/libraries/sidechain/include/sidechain/types.hpp +++ b/libraries/sidechain/include/sidechain/types.hpp @@ -32,7 +32,6 @@ enum class sidechain_proposal_type { ISSUE_PBTC, SEND_BTC_TRANSACTION, - WITHDRAW_PBTC, RETURN_PBTC_BACK }; @@ -46,5 +45,5 @@ struct prev_out } FC_REFLECT_ENUM( sidechain::payment_type, (NULLDATA)(P2PK)(P2PKH)(P2SH)(P2WPKH)(P2WSH)(P2SH_WPKH)(P2SH_WSH) ); -FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_PBTC)(SEND_BTC_TRANSACTION)(WITHDRAW_PBTC)(RETURN_PBTC_BACK) ); +FC_REFLECT_ENUM( sidechain::sidechain_proposal_type, (ISSUE_PBTC)(SEND_BTC_TRANSACTION)(RETURN_PBTC_BACK) ); FC_REFLECT( sidechain::prev_out, (hash_tx)(n_vout)(amount) ); diff --git a/libraries/sidechain/input_withdrawal_info.cpp b/libraries/sidechain/input_withdrawal_info.cpp index 3cc45398..b716956f 100644 --- a/libraries/sidechain/input_withdrawal_info.cpp +++ b/libraries/sidechain/input_withdrawal_info.cpp @@ -15,6 +15,26 @@ bool info_for_vin::comparer::operator() ( const info_for_vin& lhs, const info_fo return lhs.id < rhs.id; } +std::vector input_withdrawal_info::get_redeem_scripts( const std::vector& info_vins ) +{ + std::vector redeem_scripts; + const auto& bitcoin_address_idx = db.get_index_type().indices().get< by_address >(); + for( const auto& v : info_vins ) { + const auto& pbtc_address = bitcoin_address_idx.find( v.address ); + redeem_scripts.push_back( pbtc_address->address.get_redeem_script() ); + } + return redeem_scripts; +} + +std::vector input_withdrawal_info::get_amounts( const std::vector& info_vins ) +{ + std::vector amounts; + for( const auto& v : info_vins ) { + amounts.push_back( v.out.amount ); + } + return amounts; +} + fc::optional input_withdrawal_info::get_info_for_pw_vin() { fc::optional< primary_wallet_vout_object > vout = db.pw_vout_manager.get_latest_unused_vout(); diff --git a/libraries/sidechain/network/sidechain_net_manager.cpp b/libraries/sidechain/network/sidechain_net_manager.cpp index adae9f35..d1c6239b 100644 --- a/libraries/sidechain/network/sidechain_net_manager.cpp +++ b/libraries/sidechain/network/sidechain_net_manager.cpp @@ -113,7 +113,6 @@ void sidechain_net_manager::send_btc_tx( const sidechain::bitcoin_transaction& t FC_ASSERT( !bitcoin_client->connection_is_not_defined() ); const auto tx_hex = fc::to_hex( pack( trx ) ); - idump((tx_hex)); auto reply = bitcoin_client->send_btc_tx( tx_hex ); diff --git a/libraries/sidechain/sign_bitcoin_transaction.cpp b/libraries/sidechain/sign_bitcoin_transaction.cpp index bc282946..2c22d2b1 100644 --- a/libraries/sidechain/sign_bitcoin_transaction.cpp +++ b/libraries/sidechain/sign_bitcoin_transaction.cpp @@ -44,15 +44,16 @@ std::vector privkey_sign( const bytes& privkey, const fc::sha256 &hash, co return sig; } -std::vector sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector& info_vins, - const bytes& privkey, const secp256k1_context_t* context_sign, int hash_type ) +std::vector sign_witness_transaction_part( const bitcoin_transaction& tx, const std::vector& redeem_scripts, + const std::vector& amounts, const bytes& privkey, + const secp256k1_context_t* context_sign, int hash_type ) { - FC_ASSERT( tx.vin.size() == info_vins.size() ); + FC_ASSERT( tx.vin.size() == redeem_scripts.size() && tx.vin.size() == amounts.size() ); FC_ASSERT( !privkey.empty() ); std::vector< bytes > signatures; for( size_t i = 0; i < tx.vin.size(); i++ ) { - const auto sighash = get_signature_hash( tx, info_vins[i].script, static_cast( info_vins[i].out.amount ), i, hash_type, true ); + const auto sighash = get_signature_hash( tx, redeem_scripts[i], static_cast( amounts[i] ), i, hash_type, true ); auto sig = privkey_sign( privkey, sighash, context_sign ); sig.push_back( static_cast( hash_type ) ); @@ -61,13 +62,13 @@ std::vector sign_witness_transaction_part( const bitcoin_transaction& tx, return signatures; } -void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector& info_vins ) +void sign_witness_transaction_finalize( bitcoin_transaction& tx, const std::vector& redeem_scripts ) { - FC_ASSERT( tx.vin.size() == info_vins.size() ); + FC_ASSERT( tx.vin.size() == redeem_scripts.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( info_vins[i].script ); + tx.vin[i].scriptWitness.push_back( redeem_scripts[i] ); } } @@ -81,8 +82,11 @@ bool verify_sig( const bytes& sig, const bytes& pubkey, const bytes& msg, const return result == 1; } -std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector& info_vins, const secp256k1_context_t* context ) +std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector& redeem_scripts, + const std::vector& amounts, const secp256k1_context_t* context ) { + FC_ASSERT( redeem_scripts.size() == amounts.size() ); + using data = std::pair; struct comp { bool operator() (const data& lhs, const data& rhs) const { return lhs.first < rhs.first; } @@ -90,9 +94,9 @@ std::vector> sort_sigs( const bitcoin_transaction& tx, const std::vector> new_stacks; - for( size_t i = 0; i < info_vins.size(); i++ ) { - const std::vector& keys = get_pubkey_from_redeemScript( info_vins[i].script ); - const auto& sighash = get_signature_hash( tx, info_vins[i].script, static_cast( info_vins[i].out.amount ), i, 1, true ).str(); + for( size_t i = 0; i < redeem_scripts.size(); i++ ) { + const std::vector& keys = get_pubkey_from_redeemScript( redeem_scripts[i] ); + const auto& sighash = get_signature_hash( tx, redeem_scripts[i], static_cast( amounts[i] ), i, 1, true ).str(); bytes sighash_temp( parse_hex( sighash ) ); std::vector stack( tx.vin[i].scriptWitness ); diff --git a/tests/tests/bitcoin_sign_tests.cpp b/tests/tests/bitcoin_sign_tests.cpp index 17605e16..d47908cf 100644 --- a/tests/tests/bitcoin_sign_tests.cpp +++ b/tests/tests/bitcoin_sign_tests.cpp @@ -7,6 +7,7 @@ #include #include #include +#include #include "../common/database_fixture.hpp" using namespace sidechain; @@ -47,9 +48,9 @@ BOOST_AUTO_TEST_CASE( btc_tx_witness_signature_test ) vin.out.amount = amount; vin.script = redeemScript; - tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { vin }, privkey_1, db.context_sign, hash_type)[0] ); - tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { vin }, privkey_2, db.context_sign, hash_type)[0] ); - sign_witness_transaction_finalize( tx, { vin } ); + tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { redeemScript }, { amount }, privkey_1, db.context_sign, hash_type)[0] ); + tx.vin[0].scriptWitness.push_back( sign_witness_transaction_part( tx, { redeemScript }, { amount }, privkey_2, db.context_sign, hash_type)[0] ); + sign_witness_transaction_finalize( tx, { redeemScript } ); BOOST_CHECK( fc::to_hex( pack( tx ) ) == "0100000000010145310e878941a1b2bc2d33797ee4d89d95eaaf2e13488063a2aa9a74490f510a0100000023220020b6744de4f6ec63cc92f7c220cdefeeb1b1bed2b66c8e5706d80ec247d37e65a1ffffffff01002d3101000000001976a9143ebc40e411ed3c76f86711507ab952300890397288ac0400473044022001dd489a5d4e2fbd8a3ade27177f6b49296ba7695c40dbbe650ea83f106415fd02200b23a0602d8ff1bdf79dee118205fc7e9b40672bf31563e5741feb53fb86388501483045022100f88f040e90cc5dc6c6189d04718376ac19ed996bf9e4a3c29c3718d90ffd27180220761711f16c9e3a44f71aab55cbc0634907a1fa8bb635d971a9a01d368727bea10169522103b3623117e988b76aaabe3d63f56a4fc88b228a71e64c4cc551d1204822fe85cb2103dd823066e096f72ed617a41d3ca56717db335b1ea47a1b4c5c9dbdd0963acba621033d7c89bd9da29fa8d44db7906a9778b53121f72191184a9fee785c39180e4be153ae00000000" ); } @@ -103,29 +104,6 @@ BOOST_AUTO_TEST_CASE( get_pubkey_from_redeemScript_test ) BOOST_CHECK( keys_from_script2[0] == parse_hex( "025feceb66ffc86f38d952786c6d696c79c2dbc239dd4e91b46729d73a27fb57e9" ) ); } -std::vector create_info_vins( const std::vector& scripts, const std::vector& amounts ) -{ - std::vector info_vins; - for( size_t i = 0; i < scripts.size(); i++ ) { - info_for_vin vin; - vin.out.amount = amounts[i]; - vin.script = scripts[i]; - info_vins.push_back( vin ); - } - return info_vins; -} - -void test_sort_sigs( const bitcoin_transaction& trx, const std::vector& scripts, - const std::vector& amounts, const std::vector>& results, secp256k1_context_t* context_verify ) -{ - std::vector info_vins( create_info_vins( scripts, amounts ) ); - auto new_stacks = sort_sigs( trx, info_vins, context_verify ); - - for( size_t i = 0; i < trx.vin.size(); i++ ) { - BOOST_CHECK( new_stacks[i] == results[i] ); - } -} - BOOST_AUTO_TEST_CASE( sort_sig_test ) { bitcoin_transaction trx( fc::json::from_string( "{\"nVersion\":1,\"vin\":[{\"prevout\":{\"hash\":\"e937fd2942f0f14dd46a122e138d00cfabd93572b4876da77ab57c2a76ee73af\",\"n\":0},\"scriptSig\":\"\",\"nSequence\":4294967295,\"scriptWitness\":[\"30440220772bd2e8afe8c39d28e0c08ea81281d14239033cb93c92edf52250da542fa7c2022059ca93f98b194c9bcc8017ba3de19893fad06c8ea74430dc5fbe7eb81844598d01\",\"30440220098d274e3de29da36577f88ff851d030051b417a0309b61ba1c90d1750eee432022013946f9434893e4d9cbc23b68ec8243ed935823948d701f007edb6ccc46ac29801\",\"3045022100c2cb782558909109d5971ff29e23011b8eb4cd99e86030ac81a15b3312d897530220690080ce113caf84373ac04cc16e7f62ee5eeaf47b26d8017d2509c5d5510c0201\",\"3045022100888c5c9b5d2a4f3a17713cf665c2c65f3b9e954c2bcf3506deb9e410a33f6ca50220604f2a37e3650aded4c5811826098f8fa18af62fe07273c138440c16bdae074401\",\"3045022100cd4e8db4154b100077a30063654c4fc8473c3856064264293b931968fff9cee9022028ab2c8694218853756cca3e5ef5857694037e56e559a0004b292c7122ab355401\"]},{\"prevout\":{\"hash\":\"ae34ad50ab112e6cc51e6e3a87c48798b67255f8c8a8af9d427cbf55207ecfd1\",\"n\":0},\"scriptSig\":\"220020d85971e91d6e46473104e3f7e5eb67d885304a08dd17b3e1a0eeebe5a15f54a6\",\"nSequence\":4294967295,\"scriptWitness\":[\"3045022100b93623da6ed9a3f75082dbd77fab5492e64ae96ad4cdbb70f5a9ff1b2b30aa2602205df026319f3f21ba6f69f0be2469155c62dcf54ddfaf5f7d489d969b8364a3e401\",\"3044022010a60381cdb91d1f45579cc1d06df44b57c5af98b475089c8b349ad96a9d84fd02200840cff73d4053521dc4e7b210d20114ca82926ae96eb74633284f03f9d9861c01\",\"304402205639d8b13a6d912a3fd086abd34eb7455320aeb6b7ff148452a469f90fe636c80220035aad331677b67590845a5c6e9f8a6805d7add98cbab7047362a91717934e0001\",\"304402202945a632fe13b14099c80eb29fe6144597ca33b6fe10995a4b8756725149b5d902202b2e6a2b7bb39c7441877feaa1be68d144859ac755099704bd49eac41e12c92e01\",\"304402200e4fd2d3001736fbdabc65d50a3a04b6f99a80dc7a50b7257d65d7ced844c2320220613d8704833c50c445f56769b27067ca68299f8a462e2b62fb9e55d7c3e7046701\"]},{\"prevout\":{\"hash\":\"e04ee70b6aa2180caa32aaa4ff00c80b62e5572c369e05986d3a0e0b6d9d7455\",\"n\":0},\"scriptSig\":\"220020d85971e91d6e46473104e3f7e5eb67d885304a08dd17b3e1a0eeebe5a15f54a6\",\"nSequence\":4294967295,\"scriptWitness\":[\"30440220762212bfd15454036502ecd635314f7f81be982ea16dddf892693815745b32c7022069846f5b22b0246737396834123439556c9f8cd640006ad1ef8c70d86ca70a3e01\",\"30450221009f1c1053f45450a9e20c7735b645eb3825587ecd9dcb39a0d6de35926dbb252802204bad14928faacca9481d69960d5add5acbf7072e5230a146a7ecb6d9193b7d5001\",\"3045022100f32581419b4b46b3aa3bab0ad80202ba559fa1b086b6b02d003a2aac19782d6b02204e3132c43a12411e52f0d8b3714cb77d82136752a1e939af87d865ccda75b0ec01\",\"3045022100e145ab07653d0b2d472ebc393b5e82eee725c65573dfb458c36c7717aba5994002201cd00d40dca3120db7b38239da801765f042e248785c8d44ce4a0b8b1d57b36901\",\"3045022100f7f48205bdbb5e1690e635bf02205e4790c57aadb3f65adabd4890eb4285cfd5022056a0013f35f59c73dc2048697e0330a439e7b35804b655dbda938bdfc77ced9301\"]},{\"prevout\":{\"hash\":\"6bc22ed725ba7c164df3a878113a11e4fbc3d1bbffee0083e75cb14e7bb5bd38\",\"n\":1},\"scriptSig\":\"220020d85971e91d6e46473104e3f7e5eb67d885304a08dd17b3e1a0eeebe5a15f54a6\",\"nSequence\":4294967295,\"scriptWitness\":[\"3045022100c8a830255c4ea9ca205126701fc435d39993eca2d7024817958beea76ad3785102201cb27c7613031a4f55bc3c43683aa57f04a4f73291ad9c1076c5281bc49dc4d101\",\"304402202c1bcbd436f95e42364122f9f552466122597050962524850434bfeb0b1a721e02200f5f7cfc4d7c43c550a59918d43ee52e76e04c8da381303558f4fc83cc64e19201\",\"304402201669a5580624132b2f1e8d2a51831816846c5f93505623dc03ea6a9f01f023ed022054c69ae28483cd40ac144b7d4af4ff29292813cda425373eabd8d14624c61aae01\",\"3045022100f1b787c0466e88bbc663df7f5584dfa68416c106ab806e0b9f959c6f51b7221b022042633dfc95cde470690a52d5cc468e2f9a745fc1db2fee692b8f31cfce28c0cb01\",\"304402206468ea767ad5aa2fbe837c29ae2fee4f87063d25b9e97fc6f7f679a036a892bf022055e78030476a78d8fc9177bf2e64ccece65005493a8fc6bd1352741153e7eea601\"]}],\"vout\":[{\"value\":\"9590365272\",\"scriptPubKey\":\"00206a19177b8e4d76408c574118681f204c1a7065040636d5288af41f67c25a85f0\"},{\"value\":240000,\"scriptPubKey\":\"2102c0ded2bc1f1305fb0faac5e6c03ee3a1924234985427b6167ca569d13df435cfac\"},{\"value\":240000,\"scriptPubKey\":\"2102ec74848d166af51b430f6d130606896e1436688e935dd8407c3aa15c38d4471bac\"},{\"value\":240000,\"scriptPubKey\":\"2102cd19bf004e5d533de24bcc55d8573fe5fada438860512a9bbe37118733b34c80ac\"},{\"value\":240000,\"scriptPubKey\":\"21021d2559f259df45f16287d8f55ab41c1c2fb7099a75cc99a3f250611d99390091ac\"},{\"value\":240000,\"scriptPubKey\":\"2103e4857a5da1e9483ba14644421489790120555baccb9cf130848e0261464bb7b0ac\"},{\"value\":240000,\"scriptPubKey\":\"21028ba26c831fb21084c9bbb7059f76debbf442822adc286ee43ea3092fd666bcfaac\"},{\"value\":240000,\"scriptPubKey\":\"21030d9f1f4be73391d5814bb00cdb6ae10b4a1182a32a77672b5b744efa2e88dcdeac\"},{\"value\":240000,\"scriptPubKey\":\"2102096d78d32f51a1051c8e4f58ea99427ce335e76f6ea00c915cf6d7ac1270de51ac\"},{\"value\":240000,\"scriptPubKey\":\"2103b0184a0323802226dfaa767d0bc93e261762d3ae4457c04ca2613215365d2dc6ac\"},{\"value\":240000,\"scriptPubKey\":\"210226d279da5bfd81f7ab9ab804a3d0b44a06dd883a1f29d4671d4da4793b9d0d29ac\"},{\"value\":240000,\"scriptPubKey\":\"2103c6206bca3492f93b27a877362ffc25a57177fe0be4a7aaad661daead7703232fac\"}],\"nLockTime\":0}" ).as< bitcoin_transaction >() ); @@ -133,7 +111,10 @@ BOOST_AUTO_TEST_CASE( sort_sig_test ) std::vector amounts( fc::json::from_string( "[5993981520,1200000000,1200000000,1200000000]" ).as< std::vector >() ); std::vector> results( fc::json::from_string( "[[\"30440220098d274e3de29da36577f88ff851d030051b417a0309b61ba1c90d1750eee432022013946f9434893e4d9cbc23b68ec8243ed935823948d701f007edb6ccc46ac29801\",\"3045022100c2cb782558909109d5971ff29e23011b8eb4cd99e86030ac81a15b3312d897530220690080ce113caf84373ac04cc16e7f62ee5eeaf47b26d8017d2509c5d5510c0201\",\"3045022100888c5c9b5d2a4f3a17713cf665c2c65f3b9e954c2bcf3506deb9e410a33f6ca50220604f2a37e3650aded4c5811826098f8fa18af62fe07273c138440c16bdae074401\",\"3045022100cd4e8db4154b100077a30063654c4fc8473c3856064264293b931968fff9cee9022028ab2c8694218853756cca3e5ef5857694037e56e559a0004b292c7122ab355401\",\"30440220772bd2e8afe8c39d28e0c08ea81281d14239033cb93c92edf52250da542fa7c2022059ca93f98b194c9bcc8017ba3de19893fad06c8ea74430dc5fbe7eb81844598d01\"],[\"3044022010a60381cdb91d1f45579cc1d06df44b57c5af98b475089c8b349ad96a9d84fd02200840cff73d4053521dc4e7b210d20114ca82926ae96eb74633284f03f9d9861c01\",\"304402205639d8b13a6d912a3fd086abd34eb7455320aeb6b7ff148452a469f90fe636c80220035aad331677b67590845a5c6e9f8a6805d7add98cbab7047362a91717934e0001\",\"304402202945a632fe13b14099c80eb29fe6144597ca33b6fe10995a4b8756725149b5d902202b2e6a2b7bb39c7441877feaa1be68d144859ac755099704bd49eac41e12c92e01\",\"304402200e4fd2d3001736fbdabc65d50a3a04b6f99a80dc7a50b7257d65d7ced844c2320220613d8704833c50c445f56769b27067ca68299f8a462e2b62fb9e55d7c3e7046701\",\"3045022100b93623da6ed9a3f75082dbd77fab5492e64ae96ad4cdbb70f5a9ff1b2b30aa2602205df026319f3f21ba6f69f0be2469155c62dcf54ddfaf5f7d489d969b8364a3e401\"],[\"30450221009f1c1053f45450a9e20c7735b645eb3825587ecd9dcb39a0d6de35926dbb252802204bad14928faacca9481d69960d5add5acbf7072e5230a146a7ecb6d9193b7d5001\",\"3045022100f32581419b4b46b3aa3bab0ad80202ba559fa1b086b6b02d003a2aac19782d6b02204e3132c43a12411e52f0d8b3714cb77d82136752a1e939af87d865ccda75b0ec01\",\"3045022100e145ab07653d0b2d472ebc393b5e82eee725c65573dfb458c36c7717aba5994002201cd00d40dca3120db7b38239da801765f042e248785c8d44ce4a0b8b1d57b36901\",\"3045022100f7f48205bdbb5e1690e635bf02205e4790c57aadb3f65adabd4890eb4285cfd5022056a0013f35f59c73dc2048697e0330a439e7b35804b655dbda938bdfc77ced9301\",\"30440220762212bfd15454036502ecd635314f7f81be982ea16dddf892693815745b32c7022069846f5b22b0246737396834123439556c9f8cd640006ad1ef8c70d86ca70a3e01\"],[\"304402202c1bcbd436f95e42364122f9f552466122597050962524850434bfeb0b1a721e02200f5f7cfc4d7c43c550a59918d43ee52e76e04c8da381303558f4fc83cc64e19201\",\"304402201669a5580624132b2f1e8d2a51831816846c5f93505623dc03ea6a9f01f023ed022054c69ae28483cd40ac144b7d4af4ff29292813cda425373eabd8d14624c61aae01\",\"3045022100f1b787c0466e88bbc663df7f5584dfa68416c106ab806e0b9f959c6f51b7221b022042633dfc95cde470690a52d5cc468e2f9a745fc1db2fee692b8f31cfce28c0cb01\",\"304402206468ea767ad5aa2fbe837c29ae2fee4f87063d25b9e97fc6f7f679a036a892bf022055e78030476a78d8fc9177bf2e64ccece65005493a8fc6bd1352741153e7eea601\",\"3045022100c8a830255c4ea9ca205126701fc435d39993eca2d7024817958beea76ad3785102201cb27c7613031a4f55bc3c43683aa57f04a4f73291ad9c1076c5281bc49dc4d101\"]]" ).as< std::vector> >() ); - test_sort_sigs( trx, scripts, amounts, results, db.context_verify ); + auto new_stacks = sort_sigs( trx, scripts, amounts, db.context_verify ); + for( size_t i = 0; i < trx.vin.size(); i++ ) { + BOOST_CHECK( new_stacks[i] == results[i] ); + } } BOOST_AUTO_TEST_CASE( already_sorted_sigs_test ) @@ -143,7 +124,10 @@ BOOST_AUTO_TEST_CASE( already_sorted_sigs_test ) std::vector amounts( fc::json::from_string( "[5993981520,1200000000,1200000000,1200000000]" ).as< std::vector >() ); std::vector> results( fc::json::from_string( "[[\"30440220098d274e3de29da36577f88ff851d030051b417a0309b61ba1c90d1750eee432022013946f9434893e4d9cbc23b68ec8243ed935823948d701f007edb6ccc46ac29801\",\"3045022100c2cb782558909109d5971ff29e23011b8eb4cd99e86030ac81a15b3312d897530220690080ce113caf84373ac04cc16e7f62ee5eeaf47b26d8017d2509c5d5510c0201\",\"3045022100888c5c9b5d2a4f3a17713cf665c2c65f3b9e954c2bcf3506deb9e410a33f6ca50220604f2a37e3650aded4c5811826098f8fa18af62fe07273c138440c16bdae074401\",\"3045022100cd4e8db4154b100077a30063654c4fc8473c3856064264293b931968fff9cee9022028ab2c8694218853756cca3e5ef5857694037e56e559a0004b292c7122ab355401\",\"30440220772bd2e8afe8c39d28e0c08ea81281d14239033cb93c92edf52250da542fa7c2022059ca93f98b194c9bcc8017ba3de19893fad06c8ea74430dc5fbe7eb81844598d01\"],[\"3044022010a60381cdb91d1f45579cc1d06df44b57c5af98b475089c8b349ad96a9d84fd02200840cff73d4053521dc4e7b210d20114ca82926ae96eb74633284f03f9d9861c01\",\"304402205639d8b13a6d912a3fd086abd34eb7455320aeb6b7ff148452a469f90fe636c80220035aad331677b67590845a5c6e9f8a6805d7add98cbab7047362a91717934e0001\",\"304402202945a632fe13b14099c80eb29fe6144597ca33b6fe10995a4b8756725149b5d902202b2e6a2b7bb39c7441877feaa1be68d144859ac755099704bd49eac41e12c92e01\",\"304402200e4fd2d3001736fbdabc65d50a3a04b6f99a80dc7a50b7257d65d7ced844c2320220613d8704833c50c445f56769b27067ca68299f8a462e2b62fb9e55d7c3e7046701\",\"3045022100b93623da6ed9a3f75082dbd77fab5492e64ae96ad4cdbb70f5a9ff1b2b30aa2602205df026319f3f21ba6f69f0be2469155c62dcf54ddfaf5f7d489d969b8364a3e401\"],[\"30450221009f1c1053f45450a9e20c7735b645eb3825587ecd9dcb39a0d6de35926dbb252802204bad14928faacca9481d69960d5add5acbf7072e5230a146a7ecb6d9193b7d5001\",\"3045022100f32581419b4b46b3aa3bab0ad80202ba559fa1b086b6b02d003a2aac19782d6b02204e3132c43a12411e52f0d8b3714cb77d82136752a1e939af87d865ccda75b0ec01\",\"3045022100e145ab07653d0b2d472ebc393b5e82eee725c65573dfb458c36c7717aba5994002201cd00d40dca3120db7b38239da801765f042e248785c8d44ce4a0b8b1d57b36901\",\"3045022100f7f48205bdbb5e1690e635bf02205e4790c57aadb3f65adabd4890eb4285cfd5022056a0013f35f59c73dc2048697e0330a439e7b35804b655dbda938bdfc77ced9301\",\"30440220762212bfd15454036502ecd635314f7f81be982ea16dddf892693815745b32c7022069846f5b22b0246737396834123439556c9f8cd640006ad1ef8c70d86ca70a3e01\"],[\"304402202c1bcbd436f95e42364122f9f552466122597050962524850434bfeb0b1a721e02200f5f7cfc4d7c43c550a59918d43ee52e76e04c8da381303558f4fc83cc64e19201\",\"304402201669a5580624132b2f1e8d2a51831816846c5f93505623dc03ea6a9f01f023ed022054c69ae28483cd40ac144b7d4af4ff29292813cda425373eabd8d14624c61aae01\",\"3045022100f1b787c0466e88bbc663df7f5584dfa68416c106ab806e0b9f959c6f51b7221b022042633dfc95cde470690a52d5cc468e2f9a745fc1db2fee692b8f31cfce28c0cb01\",\"304402206468ea767ad5aa2fbe837c29ae2fee4f87063d25b9e97fc6f7f679a036a892bf022055e78030476a78d8fc9177bf2e64ccece65005493a8fc6bd1352741153e7eea601\",\"3045022100c8a830255c4ea9ca205126701fc435d39993eca2d7024817958beea76ad3785102201cb27c7613031a4f55bc3c43683aa57f04a4f73291ad9c1076c5281bc49dc4d101\"]]" ).as< std::vector> >() ); - test_sort_sigs( trx, scripts, amounts, results, db.context_verify ); + auto new_stacks = sort_sigs( trx, scripts, amounts, db.context_verify ); + for( size_t i = 0; i < trx.vin.size(); i++ ) { + BOOST_CHECK( new_stacks[i] == results[i] ); + } } BOOST_AUTO_TEST_CASE( all_signatures_are_same_test ) @@ -153,7 +137,10 @@ BOOST_AUTO_TEST_CASE( all_signatures_are_same_test ) std::vector amounts( fc::json::from_string( "[998998995,1000000000]" ).as< std::vector >() ); std::vector> results( fc::json::from_string( "[[\"304402205370c8999e097e4018b04fa3be9c27e2ff16f0c21ef363c35dfd45b4290bf0740220775506660ece404703801a3f5a13fe24c96821c7d7eb42448abe35a1035cd8c801\",\"304402205370c8999e097e4018b04fa3be9c27e2ff16f0c21ef363c35dfd45b4290bf0740220775506660ece404703801a3f5a13fe24c96821c7d7eb42448abe35a1035cd8c801\",\"304402205370c8999e097e4018b04fa3be9c27e2ff16f0c21ef363c35dfd45b4290bf0740220775506660ece404703801a3f5a13fe24c96821c7d7eb42448abe35a1035cd8c801\",\"304402205370c8999e097e4018b04fa3be9c27e2ff16f0c21ef363c35dfd45b4290bf0740220775506660ece404703801a3f5a13fe24c96821c7d7eb42448abe35a1035cd8c801\",\"304402205370c8999e097e4018b04fa3be9c27e2ff16f0c21ef363c35dfd45b4290bf0740220775506660ece404703801a3f5a13fe24c96821c7d7eb42448abe35a1035cd8c801\"],[\"3045022100ced739a6c04cf3c5e5bc760272bb6f41ecb3fa3671aa78ac1bc47629e39bb7ba02207a8693778d3b5a0c045fddc1ab23fcd971640460f150252b39993587151ff27d01\",\"3045022100ced739a6c04cf3c5e5bc760272bb6f41ecb3fa3671aa78ac1bc47629e39bb7ba02207a8693778d3b5a0c045fddc1ab23fcd971640460f150252b39993587151ff27d01\",\"3045022100ced739a6c04cf3c5e5bc760272bb6f41ecb3fa3671aa78ac1bc47629e39bb7ba02207a8693778d3b5a0c045fddc1ab23fcd971640460f150252b39993587151ff27d01\",\"3045022100ced739a6c04cf3c5e5bc760272bb6f41ecb3fa3671aa78ac1bc47629e39bb7ba02207a8693778d3b5a0c045fddc1ab23fcd971640460f150252b39993587151ff27d01\",\"3045022100ced739a6c04cf3c5e5bc760272bb6f41ecb3fa3671aa78ac1bc47629e39bb7ba02207a8693778d3b5a0c045fddc1ab23fcd971640460f150252b39993587151ff27d01\"]]" ).as< std::vector> >() ); - test_sort_sigs( trx, scripts, amounts, results, db.context_verify ); + auto new_stacks = sort_sigs( trx, scripts, amounts, db.context_verify ); + for( size_t i = 0; i < trx.vin.size(); i++ ) { + BOOST_CHECK( new_stacks[i] == results[i] ); + } } BOOST_AUTO_TEST_CASE( same_signatures_test ) @@ -163,7 +150,10 @@ BOOST_AUTO_TEST_CASE( same_signatures_test ) std::vector amounts( fc::json::from_string( "[1997997990,1000000000]" ).as< std::vector >() ); std::vector> results( fc::json::from_string( "[[\"304402204cc6d437f1f46263c36bc0605686b6072f0fb7c5991690e8ea06e8126f06a77f02205cfaa0f2e05ab9187fde9b10fbfee3ad06ae8b7120d455277186d1f8fd31b16c01\",\"304402204cc6d437f1f46263c36bc0605686b6072f0fb7c5991690e8ea06e8126f06a77f02205cfaa0f2e05ab9187fde9b10fbfee3ad06ae8b7120d455277186d1f8fd31b16c01\",\"304402204cc6d437f1f46263c36bc0605686b6072f0fb7c5991690e8ea06e8126f06a77f02205cfaa0f2e05ab9187fde9b10fbfee3ad06ae8b7120d455277186d1f8fd31b16c01\"\"30440220228c930388a0420aa9a17acdf414763bec0f57f92ecf8db51f02e3f8d82428aa0220417f2d0fbc5fd00d5d158a2e7fe7188857119b8d16d11f82f513594a28dbcbfa01\",\"3045022100d95008906e848a8165fbc0d3ed6d11643bc4814d4f8ae84c8c84a97c8c14885002206a2d703ffcca22309b843b55b746994fb08c15fbbf0aadbf900398e8768c62dc01\"],[\"3045022100c4d233c9183d91fd9f1821fb68e1180bbd6493eb66caf36438bccd8cb46a247302200d3a16ff3180fb9ffe8dd16c8ea71f461e7b940baea4c302c8d8e2ba9bf74b9201\",\"3045022100c4d233c9183d91fd9f1821fb68e1180bbd6493eb66caf36438bccd8cb46a247302200d3a16ff3180fb9ffe8dd16c8ea71f461e7b940baea4c302c8d8e2ba9bf74b9201\",\"3045022100c4d233c9183d91fd9f1821fb68e1180bbd6493eb66caf36438bccd8cb46a247302200d3a16ff3180fb9ffe8dd16c8ea71f461e7b940baea4c302c8d8e2ba9bf74b9201\",\"3045022100bdc4d1151d0567bb4e377b473100eaf41544bb547bc6d82b0a0dae8e8e833a6d022013caa911c553558abe6fdf1a6853ca6bab6912d90676595cfd4d11afd4f7966301\",\"3045022100e1262b0e14df0f6f99d850651caa6b8881f7cbf811ad549cb0d6a1b1369beec902204232af72b6bfcb21a83d555374dc622275b7c2cac31b4f56d76b87d88fdc586e01\"]]" ).as< std::vector> >() ); - test_sort_sigs( trx, scripts, amounts, results, db.context_verify ); + auto new_stacks = sort_sigs( trx, scripts, amounts, db.context_verify ); + for( size_t i = 0; i < trx.vin.size(); i++ ) { + BOOST_CHECK( new_stacks[i] == results[i] ); + } } class bitcoin_transaction_sign_evaluator_test : public bitcoin_transaction_sign_evaluator @@ -224,48 +214,67 @@ public: accounts_keys keys_map; }; -std::vector create_info_for_vins( const btc_multisig_segwit_address& addr ) +std::vector create_info_for_vins( const std::vector& addresses ) { std::vector result; - for( size_t i = 0; i < 5; i++ ) { + for( size_t i = 0; i < addresses.size(); i++ ) { info_for_vin vin; vin.out.hash_tx = "1111111111111111111111111111111111111111111111111111111111111111"; vin.out.n_vout = static_cast( i ); vin.out.amount = static_cast( i ); - std::string address = addr.get_address(); - vin.script = addr.get_redeem_script(); + vin.address = addresses[i].get_address(); + vin.script = addresses[i].get_witness_script(); result.push_back( vin ); } return result; } -void sign_transaction( bitcoin_transaction& tx, const private_key& priv_key, const std::vector& info_vins, secp256k1_context_t* context_sign ) +void sign_transaction( bitcoin_transaction& tx, const private_key& priv_key, const std::vector& redeem_scripts, + const std::vector& amounts, secp256k1_context_t* context_sign ) { const auto secret = priv_key.get_secret(); bytes key( secret.data(), secret.data() + secret.data_size() ); - auto sigs = sign_witness_transaction_part( tx, info_vins, key, context_sign, 1 ); + auto sigs = sign_witness_transaction_part( tx, redeem_scripts, amounts, key, context_sign, 1 ); for( size_t j = 0; j < tx.vin.size(); j++ ) { tx.vin[j].scriptWitness.push_back( sigs[j] ); } } +std::vector create_addresses( database& db, accounts_keys keys_map ) +{ + std::vector addresses; + for( size_t i = 0; i < 5; i++ ) { + const auto& address = db.create( [&]( bitcoin_address_object& a ) { + const private_key petra_private_key = private_key::regenerate( fc::sha256::hash( std::to_string( i ) ) ); + (--keys_map.end())->second = public_key_type( petra_private_key.get_public_key() ); + a.address = sidechain::btc_multisig_segwit_address( 5, keys_map ); + }); + addresses.push_back( address.address ); + } + return addresses; +} + BOOST_AUTO_TEST_CASE( check_sigs_normal_sigs_test ) { transaction_evaluation_state trx_eval( &db ); bitcoin_transaction_sign_evaluator_test sign_eval( trx_eval ); - btc_multisig_segwit_address address( 5, sign_eval.keys_map ); - std::vector info_for_vins = create_info_for_vins( address ); + auto addresses = create_addresses( db, sign_eval.keys_map ); + + std::vector info_for_vins = create_info_for_vins( addresses ); sidechain_condensing_tx ct( info_for_vins, std::vector() ); bitcoin_transaction transaction = ct.get_transaction(); + std::vector redeem_scripts( db.i_w_info.get_redeem_scripts( info_for_vins ) ); + std::vector amounts( db.i_w_info.get_amounts( info_for_vins ) ); + for( size_t i = 0; i < 4; i++ ) { - sign_transaction( transaction, sign_eval.private_keys[i], info_for_vins, db.context_sign ); + sign_transaction( transaction, sign_eval.private_keys[i], redeem_scripts, amounts, db.context_sign ); } const auto secret = sign_eval.private_keys[4].get_secret(); bytes key( secret.data(), secret.data() + secret.data_size() ); - auto sigs = sign_witness_transaction_part( transaction, info_for_vins, key, db.context_sign, 1 ); + auto sigs = sign_witness_transaction_part( transaction, redeem_scripts, amounts, key, db.context_sign, 1 ); const auto pub_key = sign_eval.keys_map[account_id_type(4)].key_data; bytes key_hex( public_key_data_to_bytes( pub_key ) ); @@ -277,18 +286,22 @@ BOOST_AUTO_TEST_CASE( check_sigs_extra_signature_test ) transaction_evaluation_state trx_eval( &db ); bitcoin_transaction_sign_evaluator_test sign_eval( trx_eval ); - btc_multisig_segwit_address address( 5, sign_eval.keys_map ); - std::vector info_for_vins = create_info_for_vins( address ); + const auto& addresses = create_addresses( db, sign_eval.keys_map ); + + std::vector info_for_vins = create_info_for_vins( addresses ); sidechain_condensing_tx ct( info_for_vins, std::vector() ); bitcoin_transaction transaction = ct.get_transaction(); + std::vector redeem_scripts( db.i_w_info.get_redeem_scripts( info_for_vins ) ); + std::vector amounts( db.i_w_info.get_amounts( info_for_vins ) ); + for( size_t i = 0; i < 5; i++ ) { - sign_transaction( transaction, sign_eval.private_keys[i], info_for_vins, db.context_sign ); + sign_transaction( transaction, sign_eval.private_keys[i], redeem_scripts, amounts, db.context_sign ); } const auto secret = sign_eval.private_keys[5].get_secret(); bytes key(secret.data(), secret.data() + secret.data_size()); - auto sigs = sign_witness_transaction_part( transaction, info_for_vins, key, db.context_sign, 1 ); + auto sigs = sign_witness_transaction_part( transaction, redeem_scripts, amounts, key, db.context_sign, 1 ); const auto pub_key = sign_eval.keys_map[account_id_type(5)].key_data; bytes key_hex( public_key_data_to_bytes( pub_key ) ); @@ -300,14 +313,19 @@ BOOST_AUTO_TEST_CASE( check_sigs_sign_not_match_key_test ) transaction_evaluation_state trx_eval( &db ); bitcoin_transaction_sign_evaluator_test sign_eval( trx_eval ); - btc_multisig_segwit_address address( 5, sign_eval.keys_map ); - std::vector info_for_vins = create_info_for_vins( address ); + const auto& addresses = create_addresses( db, sign_eval.keys_map ); + + std::vector info_for_vins = create_info_for_vins( addresses ); sidechain_condensing_tx ct( info_for_vins, std::vector() ); bitcoin_transaction transaction = ct.get_transaction(); const auto secret = sign_eval.private_keys[3].get_secret(); bytes key(secret.data(), secret.data() + secret.data_size()); - auto sigs = sign_witness_transaction_part( transaction, info_for_vins, key, db.context_sign, 1 ); + + std::vector redeem_scripts( db.i_w_info.get_redeem_scripts( info_for_vins ) ); + std::vector amounts( db.i_w_info.get_amounts( info_for_vins ) ); + + auto sigs = sign_witness_transaction_part( transaction, redeem_scripts, amounts, key, db.context_sign, 1 ); const auto pub_key = sign_eval.keys_map[account_id_type(5)].key_data; bytes key_hex( public_key_data_to_bytes( pub_key ) ); @@ -321,18 +339,22 @@ BOOST_AUTO_TEST_CASE( check_sigs_identical_keys_normal_tests ) sign_eval.keys_map[account_id_type( 4 )] = sign_eval.keys_map[account_id_type( 3 )]; - btc_multisig_segwit_address address( 5, sign_eval.keys_map ); - std::vector info_for_vins = create_info_for_vins( address ); + const auto& addresses = create_addresses( db, sign_eval.keys_map ); + + std::vector info_for_vins = create_info_for_vins( addresses ); sidechain_condensing_tx ct( info_for_vins, std::vector() ); bitcoin_transaction transaction = ct.get_transaction(); + std::vector redeem_scripts( db.i_w_info.get_redeem_scripts( info_for_vins ) ); + std::vector amounts( db.i_w_info.get_amounts( info_for_vins ) ); + for( size_t i = 0; i < 4; i++ ) { - sign_transaction( transaction, sign_eval.private_keys[i], info_for_vins, db.context_sign ); + sign_transaction( transaction, sign_eval.private_keys[i], redeem_scripts, amounts, db.context_sign ); } const auto secret = sign_eval.private_keys[3].get_secret(); bytes key(secret.data(), secret.data() + secret.data_size()); - auto sigs = sign_witness_transaction_part( transaction, info_for_vins, key, db.context_sign, 1 ); + auto sigs = sign_witness_transaction_part( transaction, redeem_scripts, amounts, key, db.context_sign, 1 ); const auto pub_key = sign_eval.keys_map[account_id_type(3)].key_data; bytes key_hex( public_key_data_to_bytes( pub_key ) ); @@ -346,18 +368,22 @@ BOOST_AUTO_TEST_CASE( check_sigs_identical_keys_not_normal_tests ) sign_eval.keys_map[account_id_type( 4 )] = sign_eval.keys_map[account_id_type( 3 )]; - btc_multisig_segwit_address address( 5, sign_eval.keys_map ); - std::vector info_for_vins = create_info_for_vins( address ); + const auto& addresses = create_addresses( db, sign_eval.keys_map ); + + std::vector info_for_vins = create_info_for_vins( addresses ); sidechain_condensing_tx ct( info_for_vins, std::vector() ); bitcoin_transaction transaction = ct.get_transaction(); + std::vector redeem_scripts( db.i_w_info.get_redeem_scripts( info_for_vins ) ); + std::vector amounts( db.i_w_info.get_amounts( info_for_vins ) ); + for( size_t i = 0; i < 4; i++ ) { - sign_transaction( transaction, sign_eval.private_keys[i], info_for_vins, db.context_sign ); + sign_transaction( transaction, sign_eval.private_keys[i], redeem_scripts, amounts, db.context_sign ); } const auto secret = sign_eval.private_keys[3].get_secret(); bytes key(secret.data(), secret.data() + secret.data_size()); - auto sigs = sign_witness_transaction_part( transaction, info_for_vins, key, db.context_sign, 1 ); + auto sigs = sign_witness_transaction_part( transaction, redeem_scripts, amounts, key, db.context_sign, 1 ); for( size_t j = 0; j < transaction.vin.size(); j++ ) { transaction.vin[j].scriptWitness.push_back( sigs[j] ); }