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
Initial Transaction API #130
Merged
Merged
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
1476206
Added account history plugin
brianjohnson5972 991165e
Added account history processing to applications
brianjohnson5972 65c1ceb
Added plugins to cmake and removed unintended commit
brianjohnson5972 a251af2
Moved transaction tracking into database
brianjohnson5972 3122cab
Updating chainbase submodule
brianjohnson5972 69f0bb1
Merged in upstream changes
brianjohnson5972 4a4026e
Moved object and multi index definition to its own header file and ad…
brianjohnson5972 91da030
Minor review fixes
brianjohnson5972 809bb82
Removed erroneous word in comment
brianjohnson5972 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does not compile:
db is a const ref, but
with_read_lock
is not a const method. I wonder... shouldwith_read_lock
be const?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe I "fixed" that (Otherwise Travis would complain). see commit d48ebab.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Were you able to get it to work, or is there an issue with my commit? I had a heck of a time getting the submodule commit correct, so it would not be a big shocker if it really didn't work.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, just an old submodule. Oops :]