Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement txid plugin to find transaction by hash #1904

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions libraries/app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ add_library( graphene_app

# need to link graphene_debug_witness because plugins aren't sufficiently isolated #246
target_link_libraries( graphene_app
graphene_market_history graphene_account_history graphene_elasticsearch graphene_grouped_orders
graphene_api_helper_indexes
graphene_market_history graphene_account_history graphene_elasticsearch
graphene_grouped_orders graphene_api_helper_indexes graphene_txid_plugin
graphene_chain fc graphene_db graphene_net graphene_utilities graphene_debug_witness )
target_include_directories( graphene_app
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include"
Expand Down
3 changes: 3 additions & 0 deletions libraries/app/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,9 @@ void application_impl::startup()
if( _active_plugins.find( "market_history" ) != _active_plugins.end() )
_app_options.has_market_history_plugin = true;

if( _active_plugins.find( "txid" ) != _active_plugins.end() )
_app_options.has_txid_plugin = true;

if( _options->count("api-access") ) {

fc::path api_access_file = _options->at("api-access").as<boost::filesystem::path>();
Expand Down
38 changes: 38 additions & 0 deletions libraries/app/database_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,44 @@ processed_transaction database_api_impl::get_transaction(uint32_t block_num, uin
return opt_block->transactions[trx_num];
}

optional<extended_transaction_info> database_api::get_transaction_by_id(
const transaction_id_type& txid,
optional<bool> skip_full_tx )const
{
return my->get_transaction_by_id( txid, skip_full_tx );
}

optional<extended_transaction_info> database_api_impl::get_transaction_by_id(
const transaction_id_type& txid,
optional<bool> skip_full_tx )const
{
FC_ASSERT( _app_options && _app_options->has_txid_plugin, "txid plugin is not enabled" );

const auto& idx = _db.get_index_type<transaction_position_index>().indices().get<by_txid>();
auto itr = idx.find( txid );
if( itr == idx.end() )
return {};

const auto& tx = *itr;
if( skip_full_tx.valid() && *skip_full_tx )
return tx;

extended_transaction_info tx_info(tx);
tx_info.tx = get_transaction( tx.block_num, tx.trx_in_block );
return tx_info;
}

uint64_t database_api::get_transaction_count()const
{
return my->get_transaction_count();
}

uint64_t database_api_impl::get_transaction_count()const
{
FC_ASSERT( _app_options && _app_options->has_txid_plugin, "txid plugin is not enabled" );
return _db.get_index_type<transaction_position_index>().indices().size();
}

//////////////////////////////////////////////////////////////////////
// //
// Globals //
Expand Down
5 changes: 5 additions & 0 deletions libraries/app/database_api_impl.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ class database_api_impl : public std::enable_shared_from_this<database_api_impl>
map<uint32_t, optional<block_header>> get_block_header_batch(const vector<uint32_t> block_nums)const;
optional<signed_block> get_block(uint32_t block_num)const;
processed_transaction get_transaction( uint32_t block_num, uint32_t trx_in_block )const;
optional<extended_transaction_info> get_transaction_by_id(
const transaction_id_type& txid,
optional<bool> skip_full_tx = {} )const;
uint64_t get_transaction_count()const;


// Globals
chain_property_object get_chain_properties()const;
Expand Down
15 changes: 15 additions & 0 deletions libraries/app/include/graphene/app/api_objects.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,14 @@

#include <graphene/api_helper_indexes/api_helper_indexes.hpp>
#include <graphene/market_history/market_history_plugin.hpp>
#include <graphene/plugins/txid/txid_plugin.hpp>

#include <fc/optional.hpp>

namespace graphene { namespace app {
using namespace graphene::chain;
using namespace graphene::market_history;
using namespace graphene::plugins::txid;

struct more_data
{
Expand Down Expand Up @@ -78,6 +80,15 @@ namespace graphene { namespace app {
more_data more_data_available;
};

/// @brief A transaction's position in the blockchain and optionally the full transaction
struct extended_transaction_info : public transaction_position_object
{
extended_transaction_info() : transaction_position_object() {}
extended_transaction_info( const transaction_position_object& tx ) : transaction_position_object(tx) {}

optional<processed_transaction> tx; ///< The full transaction
};

struct order
{
string price;
Expand Down Expand Up @@ -175,6 +186,10 @@ FC_REFLECT( graphene::app::full_account,
(more_data_available)
)

FC_REFLECT_DERIVED( graphene::app::extended_transaction_info,
(graphene::plugins::txid::transaction_position_object),
(tx) )

FC_REFLECT( graphene::app::order, (price)(quote)(base) );
FC_REFLECT( graphene::app::order_book, (base)(quote)(bids)(asks) );
FC_REFLECT( graphene::app::market_ticker,
Expand Down
1 change: 1 addition & 0 deletions libraries/app/include/graphene/app/application.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace graphene { namespace app {
public:
bool enable_subscribe_to_all = false;
bool has_market_history_plugin = false;
bool has_txid_plugin = false;
uint64_t api_limit_get_account_history_operations = 100;
uint64_t api_limit_get_account_history = 100;
uint64_t api_limit_get_grouped_limit_orders = 101;
Expand Down
24 changes: 24 additions & 0 deletions libraries/app/include/graphene/app/database_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ namespace graphene { namespace app {

using namespace graphene::chain;
using namespace graphene::market_history;
using namespace graphene::plugins::txid;

using std::string;
using std::vector;
using std::map;
Expand Down Expand Up @@ -188,6 +190,26 @@ class database_api
*/
optional<signed_transaction> get_recent_transaction_by_id( const transaction_id_type& txid )const;

/**
* @brief Search for an individual transaction by its hash
* @param txid hash of the transaction
* @param skip_full_tx whether to not return the full transaction data, optional,
* if omitted or set to @a false, will return the full transaction data,
* if set to @a true, will not return full transaction data
* @return info about the transaction if found, or @a null if not found
* @note This API can only find a transaction if it is already included in a block.
* For pending transactions, try @ref get_recent_transaction_by_id.
*/
optional<extended_transaction_info> get_transaction_by_id(
const transaction_id_type& txid,
optional<bool> skip_full_tx = {} )const;

/**
* @brief Return total number of transactions in the blockchain
* @return total number of transactions in the blockchain
*/
uint64_t get_transaction_count()const;

/////////////
// Globals //
/////////////
Expand Down Expand Up @@ -912,6 +934,8 @@ FC_API(graphene::app::database_api,
(get_block)
(get_transaction)
(get_recent_transaction_by_id)
(get_transaction_by_id)
(get_transaction_count)

// Globals
(get_chain_properties)
Expand Down
1 change: 1 addition & 0 deletions libraries/plugins/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ add_subdirectory( debug_witness )
add_subdirectory( snapshot )
add_subdirectory( es_objects )
add_subdirectory( api_helper_indexes )
add_subdirectory( txid )
23 changes: 23 additions & 0 deletions libraries/plugins/txid/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
file(GLOB HEADERS "include/graphene/plugins/txid/*.hpp")

add_library( graphene_txid_plugin
txid_plugin.cpp
)

target_link_libraries( graphene_txid_plugin graphene_chain graphene_app )
target_include_directories( graphene_txid_plugin
PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" )

if(MSVC)
set_source_files_properties( txid_plugin.cpp PROPERTIES COMPILE_FLAGS "/bigobj" )
endif(MSVC)

install( TARGETS
graphene_txid_plugin

RUNTIME DESTINATION bin
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
)
INSTALL( FILES ${HEADERS} DESTINATION "include/graphene/plugins/txid" )

121 changes: 121 additions & 0 deletions libraries/plugins/txid/include/graphene/plugins/txid/txid_plugin.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/*
* Copyright (c) 2019 Abit More, and contributors.
*
* The MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#pragma once

#include <graphene/app/plugin.hpp>

#include <graphene/protocol/types.hpp>

#include <boost/multi_index/composite_key.hpp>

namespace graphene { namespace plugins { namespace txid {

using namespace boost::multi_index;

using namespace graphene::db;
using namespace graphene::protocol;

//
// Plugins should #define their SPACE_ID's so plugins with
// conflicting SPACE_ID assignments can be compiled into the
// same binary (by simply re-assigning some of the conflicting #defined
// SPACE_ID's in a build script).
//
// Assignment of SPACE_ID's cannot be done at run-time because
// various template automagic depends on them being known at compile
// time.
//
#ifndef TXID_PLUGIN_SPACE_ID
#define TXID_PLUGIN_SPACE_ID 8
#endif

enum txid_plugin_object_type
{
transaction_position_object_type = 0
};

/// @brief This data structure indicates where a transaction is included in the blockchain
struct transaction_position_object : public abstract_object<transaction_position_object>
{
static const uint8_t space_id = TXID_PLUGIN_SPACE_ID;
static const uint8_t type_id = transaction_position_object_type;

/// The hash of the transaction
transaction_id_type trx_id;
/// The number (height) of the block that includes the transaction
uint32_t block_num = 0;
/// The index (sequence number) of the transaction in the block, starts from 0
uint16_t trx_in_block = 0;
};


struct by_txid;
struct by_block;

typedef multi_index_container<
transaction_position_object,
indexed_by<
ordered_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
ordered_unique< tag<by_txid>,
member< transaction_position_object, transaction_id_type, &transaction_position_object::trx_id > >,
ordered_unique< tag<by_block>,
composite_key< transaction_position_object,
member< transaction_position_object, uint32_t, &transaction_position_object::block_num >,
member< transaction_position_object, uint16_t, &transaction_position_object::trx_in_block >
>
>
>
> transaction_position_multi_index_type;

typedef generic_index<transaction_position_object, transaction_position_multi_index_type> transaction_position_index;


namespace detail
{
class txid_plugin_impl;
}

class txid_plugin : public graphene::app::plugin
{
public:
txid_plugin();
virtual ~txid_plugin();

std::string plugin_name()const override;
std::string plugin_description()const override;
virtual void plugin_set_program_options(
boost::program_options::options_description& cli,
boost::program_options::options_description& cfg) override;
virtual void plugin_initialize(const boost::program_options::variables_map& options) override;
virtual void plugin_startup() override;

friend class detail::txid_plugin_impl;
std::unique_ptr<detail::txid_plugin_impl> my;
};

} } } //graphene::plugins::txid

FC_REFLECT_DERIVED( graphene::plugins::txid::transaction_position_object,
(graphene::db::object),
(trx_id)(block_num)(trx_in_block) )
Loading