This repository has been archived by the owner on Aug 2, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #130 from brianjohnson5972/master
Initial Transaction API
- Loading branch information
Showing
14 changed files
with
371 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
file(GLOB HEADERS "include/eos/account_history_api_plugin/*.hpp") | ||
add_library( account_history_api_plugin | ||
account_history_api_plugin.cpp | ||
${HEADERS} ) | ||
|
||
target_link_libraries( account_history_api_plugin account_history_plugin chain_plugin http_plugin appbase ) | ||
target_include_directories( account_history_api_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) | ||
|
||
install( TARGETS | ||
account_history_api_plugin | ||
|
||
RUNTIME DESTINATION bin | ||
LIBRARY DESTINATION lib | ||
ARCHIVE DESTINATION lib | ||
) | ||
install( FILES ${HEADERS} DESTINATION "include/eos/account_history_api_plugin" ) |
48 changes: 48 additions & 0 deletions
48
plugins/account_history_api_plugin/account_history_api_plugin.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
#include <eos/account_history_api_plugin/account_history_api_plugin.hpp> | ||
#include <eos/chain/chain_controller.hpp> | ||
#include <eos/chain/exceptions.hpp> | ||
|
||
#include <fc/io/json.hpp> | ||
|
||
namespace eos { | ||
|
||
using namespace eos; | ||
|
||
account_history_api_plugin::account_history_api_plugin(){} | ||
account_history_api_plugin::~account_history_api_plugin(){} | ||
|
||
void account_history_api_plugin::set_program_options(options_description&, options_description&) {} | ||
void account_history_api_plugin::plugin_initialize(const variables_map&) {} | ||
|
||
#define CALL(api_name, api_handle, api_namespace, call_name) \ | ||
{std::string("/v1/" #api_name "/" #call_name), \ | ||
[this, api_handle](string, string body, url_response_callback cb) mutable { \ | ||
try { \ | ||
if (body.empty()) body = "{}"; \ | ||
auto result = api_handle.call_name(fc::json::from_string(body).as<api_namespace::call_name ## _params>()); \ | ||
cb(200, fc::json::to_string(result)); \ | ||
} catch (fc::eof_exception) { \ | ||
cb(400, "Invalid arguments"); \ | ||
elog("Unable to parse arguments: ${args}", ("args", body)); \ | ||
} catch (fc::exception& e) { \ | ||
cb(500, e.to_detail_string()); \ | ||
elog("Exception encountered while processing ${call}: ${e}", ("call", #api_name "." #call_name)("e", e)); \ | ||
} \ | ||
}} | ||
|
||
#define CHAIN_RO_CALL(call_name) CALL(account_history, ro_api, account_history_apis::read_only, call_name) | ||
#define CHAIN_RW_CALL(call_name) CALL(account_history, rw_api, account_history_apis::read_write, call_name) | ||
|
||
void account_history_api_plugin::plugin_startup() { | ||
ilog( "starting account_history_api_plugin" ); | ||
auto ro_api = app().get_plugin<account_history_plugin>().get_read_only_api(); | ||
auto rw_api = app().get_plugin<account_history_plugin>().get_read_write_api(); | ||
|
||
app().get_plugin<http_plugin>().add_api({ | ||
CHAIN_RO_CALL(get_transaction) | ||
}); | ||
} | ||
|
||
void account_history_api_plugin::plugin_shutdown() {} | ||
|
||
} |
28 changes: 28 additions & 0 deletions
28
..._history_api_plugin/include/eos/account_history_api_plugin/account_history_api_plugin.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#pragma once | ||
#include <eos/account_history_plugin/account_history_plugin.hpp> | ||
#include <eos/chain_plugin/chain_plugin.hpp> | ||
#include <eos/http_plugin/http_plugin.hpp> | ||
|
||
#include <appbase/application.hpp> | ||
|
||
namespace eos { | ||
|
||
using namespace appbase; | ||
|
||
class account_history_api_plugin : public plugin<account_history_api_plugin> { | ||
public: | ||
APPBASE_PLUGIN_REQUIRES((account_history_plugin)(chain_plugin)(http_plugin)) | ||
|
||
account_history_api_plugin(); | ||
virtual ~account_history_api_plugin(); | ||
|
||
virtual void set_program_options(options_description&, options_description&) override; | ||
|
||
void plugin_initialize(const variables_map&); | ||
void plugin_startup(); | ||
void plugin_shutdown(); | ||
|
||
private: | ||
}; | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
file(GLOB HEADERS "include/eos/account_history_plugin/*.hpp") | ||
add_library( account_history_plugin | ||
account_history_plugin.cpp | ||
${HEADERS} ) | ||
|
||
target_link_libraries( account_history_plugin chain_plugin eos_chain appbase ) | ||
target_include_directories( account_history_plugin PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/include" ) | ||
|
||
install( TARGETS | ||
account_history_plugin | ||
|
||
RUNTIME DESTINATION bin | ||
LIBRARY DESTINATION lib | ||
ARCHIVE DESTINATION lib | ||
) | ||
install( FILES ${HEADERS} DESTINATION "include/eos/account_history_plugin" ) |
132 changes: 132 additions & 0 deletions
132
plugins/account_history_plugin/account_history_plugin.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,132 @@ | ||
#include <eos/account_history_plugin/account_history_plugin.hpp> | ||
#include <eos/account_history_plugin/account_history_object.hpp> | ||
#include <eos/chain/chain_controller.hpp> | ||
#include <eos/chain/config.hpp> | ||
#include <eos/chain/exceptions.hpp> | ||
#include <eos/chain/transaction.hpp> | ||
#include <eos/chain/types.hpp> | ||
|
||
#include <fc/crypto/sha256.hpp> | ||
#include <fc/io/json.hpp> | ||
#include <fc/variant.hpp> | ||
|
||
#include <boost/multi_index/hashed_index.hpp> | ||
#include <boost/multi_index/mem_fun.hpp> | ||
#include <eos/chain/multi_index_includes.hpp> | ||
|
||
namespace fc { class variant; } | ||
|
||
namespace eos { | ||
|
||
using chain::block_id_type; | ||
using chain::ProcessedTransaction; | ||
using chain::signed_block; | ||
using boost::multi_index_container; | ||
using chain::transaction_id_type; | ||
using namespace boost::multi_index; | ||
|
||
class account_history_plugin_impl { | ||
public: | ||
ProcessedTransaction get_transaction(const chain::transaction_id_type& transaction_id) const; | ||
void applied_block(const signed_block&); | ||
chain_plugin* chain_plug; | ||
private: | ||
|
||
optional<block_id_type> find_block_id(const transaction_id_type& transaction_id) const; | ||
}; | ||
|
||
optional<block_id_type> account_history_plugin_impl::find_block_id(const transaction_id_type& transaction_id) const | ||
{ | ||
const auto& db = chain_plug->chain().get_database(); | ||
optional<block_id_type> block_id; | ||
db.with_read_lock( [&]() { | ||
const auto& trx_idx = db.get_index<transaction_history_multi_index, by_trx_id>(); | ||
auto transaction_history = trx_idx.find( transaction_id ); | ||
if (transaction_history != trx_idx.end()) | ||
block_id = transaction_history->block_id; | ||
} ); | ||
return block_id; | ||
} | ||
|
||
ProcessedTransaction account_history_plugin_impl::get_transaction(const chain::transaction_id_type& transaction_id) const | ||
{ | ||
auto block_id = find_block_id(transaction_id); | ||
if( block_id.valid() ) | ||
{ | ||
auto block = chain_plug->chain().fetch_block_by_id(*block_id); | ||
if (block.valid()) | ||
{ | ||
for (const auto& cycle : block->cycles) | ||
for (const auto& thread : cycle) | ||
for (const auto& trx : thread.user_input) | ||
if (trx.id() == transaction_id) | ||
return trx; | ||
} | ||
|
||
// ERROR in indexing logic | ||
FC_ASSERT(block, "Transaction with ID ${tid} was indexed as being in block ID ${bid}, but no such block was found", ("tid", transaction_id)("bid", block_id)); | ||
FC_THROW("Transaction with ID ${tid} was indexed as being in block ID ${bid}, but was not found in that block", ("tid", transaction_id)("bid", block_id)); | ||
} | ||
|
||
#warning TODO: lookup of recent transactions | ||
FC_THROW_EXCEPTION(chain::unknown_transaction_exception, | ||
"Could not find transaction for: ${id}", ("id", transaction_id.str())); | ||
} | ||
|
||
void account_history_plugin_impl::applied_block(const signed_block& block) | ||
{ | ||
const auto block_id = block.id(); | ||
auto& db = chain_plug->chain().get_mutable_database(); | ||
for (const auto& cycle : block.cycles) | ||
for (const auto& thread : cycle) | ||
for (const auto& trx : thread.user_input) { | ||
db.create<transaction_history_object>([&block_id,&trx](transaction_history_object& transaction_history) { | ||
transaction_history.block_id = block_id; | ||
transaction_history.transaction_id = trx.id(); | ||
}); | ||
} | ||
} | ||
|
||
|
||
account_history_plugin::account_history_plugin() | ||
:my(new account_history_plugin_impl()) | ||
{ | ||
} | ||
|
||
account_history_plugin::~account_history_plugin() | ||
{ | ||
} | ||
|
||
void account_history_plugin::set_program_options(options_description& cli, options_description& cfg) | ||
{ | ||
} | ||
|
||
void account_history_plugin::plugin_initialize(const variables_map& options) | ||
{ | ||
} | ||
|
||
void account_history_plugin::plugin_startup() | ||
{ | ||
my->chain_plug = app().find_plugin<chain_plugin>(); | ||
auto& db = my->chain_plug->chain().get_mutable_database(); | ||
db.add_index<transaction_history_multi_index>(); | ||
|
||
my->chain_plug->chain().applied_block.connect ([&impl = my](const signed_block& block) { | ||
impl->applied_block(block); | ||
}); | ||
} | ||
|
||
void account_history_plugin::plugin_shutdown() | ||
{ | ||
} | ||
|
||
namespace account_history_apis { | ||
|
||
read_only::get_transaction_results read_only::get_transaction(const read_only::get_transaction_params& params) const | ||
{ | ||
auto trx = account_history->get_transaction(params.transaction_id); | ||
return { account_history->chain_plug->chain().transaction_to_variant(trx) }; | ||
} | ||
|
||
} // namespace account_history_apis | ||
} // namespace eos |
35 changes: 35 additions & 0 deletions
35
plugins/account_history_plugin/include/eos/account_history_plugin/account_history_object.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
#pragma once | ||
|
||
#include <chainbase/chainbase.hpp> | ||
|
||
namespace eos { | ||
using chain::block_id_type; | ||
using chain::transaction_id_type; | ||
using namespace boost::multi_index; | ||
|
||
class transaction_history_object : public chainbase::object<chain::transaction_history_object_type, transaction_history_object> { | ||
OBJECT_CTOR(transaction_history_object) | ||
|
||
id_type id; | ||
block_id_type block_id; | ||
transaction_id_type transaction_id; | ||
}; | ||
|
||
struct by_id; | ||
struct by_trx_id; | ||
using transaction_history_multi_index = chainbase::shared_multi_index_container< | ||
transaction_history_object, | ||
indexed_by< | ||
ordered_unique<tag<by_id>, BOOST_MULTI_INDEX_MEMBER(transaction_history_object, transaction_history_object::id_type, id)>, | ||
hashed_unique<tag<by_trx_id>, BOOST_MULTI_INDEX_MEMBER(transaction_history_object, transaction_id_type, transaction_id), std::hash<transaction_id_type>> | ||
> | ||
>; | ||
|
||
typedef chainbase::generic_index<transaction_history_multi_index> transaction_history_index; | ||
|
||
} | ||
|
||
CHAINBASE_SET_INDEX_TYPE( eos::transaction_history_object, eos::transaction_history_multi_index ) | ||
|
||
FC_REFLECT( eos::transaction_history_object, (block_id)(transaction_id) ) | ||
|
72 changes: 72 additions & 0 deletions
72
plugins/account_history_plugin/include/eos/account_history_plugin/account_history_plugin.hpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
#pragma once | ||
#include <appbase/application.hpp> | ||
|
||
#include <eos/chain_plugin/chain_plugin.hpp> | ||
|
||
namespace fc { class variant; } | ||
|
||
namespace eos { | ||
using chain::transaction_id_type; | ||
using std::shared_ptr; | ||
using namespace appbase; | ||
using chain::Name; | ||
using fc::optional; | ||
using chain::uint128_t; | ||
|
||
typedef shared_ptr<class account_history_plugin_impl> account_history_ptr; | ||
typedef shared_ptr<const class account_history_plugin_impl> account_history_const_ptr; | ||
|
||
namespace account_history_apis { | ||
struct empty{}; | ||
|
||
class read_only { | ||
account_history_const_ptr account_history; | ||
|
||
public: | ||
read_only(account_history_const_ptr&& account_history) | ||
: account_history(account_history) {} | ||
|
||
struct get_transaction_params { | ||
chain::transaction_id_type transaction_id; | ||
}; | ||
struct get_transaction_results { | ||
fc::variant transaction; | ||
}; | ||
|
||
get_transaction_results get_transaction(const get_transaction_params& params) const; | ||
|
||
}; | ||
|
||
class read_write { | ||
account_history_ptr account_history; | ||
|
||
public: | ||
read_write(account_history_ptr account_history) : account_history(account_history) {} | ||
}; | ||
} // namespace account_history_apis | ||
|
||
class account_history_plugin : public plugin<account_history_plugin> { | ||
public: | ||
APPBASE_PLUGIN_REQUIRES((chain_plugin)) | ||
|
||
account_history_plugin(); | ||
virtual ~account_history_plugin(); | ||
|
||
virtual void set_program_options(options_description& cli, options_description& cfg) override; | ||
|
||
void plugin_initialize(const variables_map& options); | ||
void plugin_startup(); | ||
void plugin_shutdown(); | ||
|
||
account_history_apis::read_only get_read_only_api() const { return account_history_apis::read_only(account_history_const_ptr(my)); } | ||
account_history_apis::read_write get_read_write_api() { return account_history_apis::read_write(my); } | ||
|
||
private: | ||
account_history_ptr my; | ||
}; | ||
|
||
} | ||
|
||
FC_REFLECT(eos::account_history_apis::empty, ) | ||
FC_REFLECT(eos::account_history_apis::read_only::get_transaction_params, (transaction_id) ) | ||
FC_REFLECT(eos::account_history_apis::read_only::get_transaction_results, (transaction) ) |
Oops, something went wrong.