// Validate script consensus conformance based on flags provided. static bool check_consensus(const script& prevout_script, const transaction& current_tx, size_t input_index, uint32_t options) { BITCOIN_ASSERT(input_index <= max_uint32); BITCOIN_ASSERT(input_index < current_tx.inputs.size()); const auto input_index32 = static_cast<uint32_t>(input_index); const auto bip16_enabled = ((options & validation_options::p2sh) != 0); #ifdef WITH_CONSENSUS using namespace bc::consensus; const auto previous_output_script = prevout_script.to_data(false); data_chunk current_transaction = current_tx.to_data(); const auto flags = (bip16_enabled ? verify_flags_p2sh : verify_flags_none); const auto result = verify_script(current_transaction.data(), current_transaction.size(), previous_output_script.data(), previous_output_script.size(), input_index32, flags); const auto valid = (result == verify_result::verify_result_eval_true); #else // Copy the const prevout script so it can be run. auto previous_output_script = prevout_script; const auto& current_input_script = current_tx.inputs[input_index].script; const auto valid = script::verify(current_input_script, previous_output_script, current_tx, input_index32, bip16_enabled); #endif if (!valid) log::warning(LOG_VALIDATE) << "Invalid transaction [" << encode_hash(current_tx.hash()) << "]"; return valid; }
// A new transaction has been received, add it to the memory pool. void transaction_pool::add(const transaction& tx, confirm_handler handler) { // When a new tx is added to the buffer drop the oldest. if (maintain_consistency_ && buffer_.size() == buffer_.capacity()) delete_package(error::pool_filled); // Store a precomputed tx hash to make lookups faster. buffer_.push_back({ tx.hash(), tx, handler }); }
// Validate script consensus conformance based on flags provided. bool validate_transaction::check_consensus(const script& prevout_script, const transaction& current_tx, size_t input_index, uint32_t flags) { BITCOIN_ASSERT(input_index <= max_uint32); BITCOIN_ASSERT(input_index < current_tx.inputs.size()); const auto input_index32 = static_cast<uint32_t>(input_index); #ifdef WITH_CONSENSUS using namespace bc::consensus; const auto previous_output_script = prevout_script.to_data(false); data_chunk current_transaction = current_tx.to_data(); // Convert native flags to libbitcoin-consensus flags. uint32_t consensus_flags = verify_flags_none; if ((flags & script_context::bip16_enabled) != 0) consensus_flags |= verify_flags_p2sh; if ((flags & script_context::bip65_enabled) != 0) consensus_flags |= verify_flags_checklocktimeverify; if ((flags & script_context::bip66_enabled) != 0) consensus_flags |= verify_flags_dersig; const auto result = verify_script(current_transaction.data(), current_transaction.size(), previous_output_script.data(), previous_output_script.size(), input_index32, consensus_flags); const auto valid = (result == verify_result::verify_result_eval_true); #else // Copy the const prevout script so it can be run. auto previous_output_script = prevout_script; const auto& current_input_script = current_tx.inputs[input_index].script; const auto valid = script::verify(current_input_script, previous_output_script, current_tx, input_index32, flags); #endif if (!valid) log::warning(LOG_BLOCKCHAIN) << "Invalid transaction [" << encode_hash(current_tx.hash()) << "]"; return valid; }
bool transaction_pool::delete_single(const transaction& tx, const code& ec) { return delete_single(tx, tx.hash(), ec); }