예제 #1
0
bool inventory_vector::already_have(
    db_tx & tx_db, const inventory_vector & inv
    )
{
    switch (inv.type())
    {
        case type_error:
        {
            // ...
        }
        break;
        case type_msg_tx:
        {
            auto tx_in_map = transaction_pool::instance().exists(inv.hash());
            
            return
                tx_in_map ||
                globals::instance().orphan_transactions().count(inv.hash()) ||
                tx_db.contains_transaction(inv.hash()
            );
        }
        break;
        case type_msg_block:
        {
            return
                globals::instance().block_indexes().count(inv.hash()) ||
                globals::instance().orphan_blocks().count(inv.hash())
            ;
        }
        break;
    }
    
    return true;
}
예제 #2
0
std::pair<bool, std::string> transaction_wallet::accept_wallet_transaction(
    db_tx & tx_db
    )
{
    /**
     * Add previous supporting transactions first.
     */
    for (auto & i : m_previous_transactions)
    {
        if (i.is_coin_base() == false && i.is_coin_stake() == false)
        {
            auto hash_tx = i.get_hash();
            
            if (
                transaction_pool::instance().exists(hash_tx) == false &&
                tx_db.contains_transaction(hash_tx) == false
                )
            {
                i.accept_to_transaction_pool(tx_db);
            }
        }
    }
    
    return transaction::accept_to_transaction_pool(tx_db);
}
예제 #3
0
void transaction_wallet::relay_wallet_transaction(
    db_tx & tx_db,
    const std::shared_ptr<tcp_connection_manager> & connection_manager,
    const bool & use_udp
    )
{
    for (auto & i : m_previous_transactions)
    {
        if ((i.is_coin_base() || i.is_coin_stake()) == false)
        {
            auto hash_tx = i.get_hash();
            
            if (tx_db.contains_transaction(hash_tx) == false)
            {
                inventory_vector inv(
                    inventory_vector::type_msg_tx, hash_tx
                );
                
                data_buffer buffer;
            
                i.encode(buffer);
                
                for (auto & j : connection_manager->tcp_connections())
                {
                    if (auto t = j.second.lock())
                    {
                        t->send_relayed_inv_message(inv, buffer);
                    }
                }
            }
        }
    }
    
    if ((is_coin_base() || is_coin_stake()) == false)
    {
        auto hash_tx = get_hash();
        
        if (tx_db.contains_transaction(hash_tx) == false)
        {
            log_debug(
                "Transaction wallet is relaying " <<
                hash_tx.to_string().substr(0, 10) << "."
            );

            /**
             * Allocate the inventory_vector.
             */
            inventory_vector inv(inventory_vector::type_msg_tx, hash_tx);
            
            /**
             * Allocate the data_buffer.
             */
            data_buffer buffer;
            
            /**
             * Encode the transaction.
             */
            reinterpret_cast<transaction *> (this)->encode(buffer);
            
            /**
             * Relay the transaction over TCP.
             */
            for (auto & i : connection_manager->tcp_connections())
            {
                if (auto t = i.second.lock())
                {
                    t->send_relayed_inv_message(inv, buffer);
                }
            }
            
            if (use_udp)
            {
                if (wallet_)
                {
                    /**
                     * Allocate the message.
                     */
                    message msg(inv.command(), buffer);

                    /**
                     * Encode the message.
                     */
                    msg.encode();
        
                    /**
                     * Allocate the UDP packet.
                     */
                    std::vector<std::uint8_t> udp_packet(msg.size());
                    
                    /**
                     * Copy the message to the UDP packet.
                     */
                    std::memcpy(&udp_packet[0], msg.data(), msg.size());
            
                    /**
                     * Broadcast the message over UDP.
                     */
                    const_cast<stack_impl *> (wallet_->get_stack_impl()
                        )->get_database_stack()->broadcast(udp_packet
                    );
                }
            }
        }
    }
}