Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Add support for auto-signing testing transactions
Browse files Browse the repository at this point in the history
Implement automatic signing of transactions in the test framework.
Currently disabled, as it's not yet working
  • Loading branch information
nathanielhourt committed Aug 9, 2017
1 parent 16306e9 commit 7eb2013
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 12 deletions.
37 changes: 37 additions & 0 deletions tests/common/database_fixture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include <eos/chain/account_object.hpp>
#include <eos/chain/producer_object.hpp>
#include <eos/chain/authority_checker.hpp>

#include <eos/utilities/tempdir.hpp>

Expand All @@ -37,6 +38,8 @@
#include <fc/crypto/digest.hpp>
#include <fc/smart_ref_impl.hpp>

#include <boost/range/adaptor/map.hpp>

#include <iostream>
#include <iomanip>
#include <sstream>
Expand Down Expand Up @@ -94,9 +97,15 @@ private_key_type testing_fixture::get_private_key(const public_key_type& public_
return itr->second;
}

flat_set<public_key_type> testing_fixture::available_keys() const {
auto range = key_ring | boost::adaptors::map_keys;
return {range.begin(), range.end()};
}

testing_blockchain::testing_blockchain(chainbase::database& db, fork_database& fork_db, block_log& blocklog,
chain_initializer_interface& initializer, testing_fixture& fixture)
: chain_controller(db, fork_db, blocklog, initializer, native_contract::make_administrator()),
db(db),
fixture(fixture) {}

void testing_blockchain::produce_blocks(uint32_t count, uint32_t blocks_to_miss) {
Expand Down Expand Up @@ -157,6 +166,34 @@ types::PublicKey testing_blockchain::get_block_signing_key(const types::AccountN
return get_database().get<producer_object, by_owner>(producerName).signing_key;
}

void testing_blockchain::sign_transaction(SignedTransaction& trx) {
auto GetAuthority = [this](const types::AccountPermission& permission) {
auto key = boost::make_tuple(permission.account, permission.permission);
return db.get<permission_object, by_owner>(key).auth;
};
auto checker = MakeAuthorityChecker(GetAuthority, fixture.available_keys());

for (const auto& message : trx.messages)
for (const auto& authorization : message.authorization)
if (!checker.satisfied(authorization))
elog("Attempting to automatically sign transaction, but testing_fixture doesn't have the keys!");

for (const auto& key : checker.used_keys())
// TODO: Use a real chain_id here
trx.sign(fixture.get_private_key(key), chain_id_type{});
}

ProcessedTransaction testing_blockchain::push_transaction(SignedTransaction trx, uint32_t skip_flags) {
if (skip_trx_sigs)
skip_flags |= chain_controller::skip_transaction_signatures;

if (auto_sign_trxs) {
sign_transaction(trx);
}

return chain_controller::push_transaction(trx, skip_flags);
}

void testing_network::connect_blockchain(testing_blockchain& new_database) {
if (blockchains.count(&new_database))
return;
Expand Down
20 changes: 20 additions & 0 deletions tests/common/database_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ class testing_fixture {

void store_private_key(const private_key_type& key);
private_key_type get_private_key(const public_key_type& public_key) const;
flat_set<public_key_type> available_keys() const;

protected:
std::vector<fc::temp_directory> anonymous_temp_dirs;
Expand Down Expand Up @@ -178,8 +179,27 @@ class testing_blockchain : public chain_controller {
/// @brief Get the specified block producer's signing key
PublicKey get_block_signing_key(const AccountName& producerName);

/// @brief Attempt to sign the provided transaction using the keys available to the testing_fixture
void sign_transaction(SignedTransaction& trx);

/// @brief Override push_transaction to apply testing policies
ProcessedTransaction push_transaction(SignedTransaction trx, uint32_t skip_flags = 0);

/// @brief Set whether testing_blockchain::push_transaction checks signatures by default
/// @param skip_sigs If true, push_transaction will skip signature checks; otherwise, no changes will be made
void set_skip_transaction_signature_checking(bool skip_sigs) {
skip_trx_sigs = skip_sigs;
}
/// @brief Set whether testing_blockchain::push_transaction attempts to sign transactions or not
void set_auto_sign_transactions(bool auto_sign) {
auto_sign_trxs = auto_sign;
}

protected:
chainbase::database& db;
testing_fixture& fixture;
bool skip_trx_sigs = true;
bool auto_sign_trxs = false;
};

using boost::signals2::scoped_connection;
Expand Down
24 changes: 12 additions & 12 deletions tests/common/macro_support.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"newaccount", types::newaccount{#creator, #name, owner, active, recovery, deposit}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Created account " << #name); \
}
#define MKACCT2(chain, name) \
Expand Down Expand Up @@ -83,7 +83,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"updateauth", types::updateauth{#account, authname, parentname, auth}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Set " << #account << "'s " << authname << " authority."); \
}

Expand All @@ -96,7 +96,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"deleteauth", types::deleteauth{#account, authname}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Deleted " << #account << "'s " << authname << " authority."); \
}

Expand All @@ -109,7 +109,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"linkauth", types::linkauth{#account, #codeacct, messagetype, authname}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Link " << #codeacct << "::" << messagetype << " to " << #account \
<< "'s " << authname << " authority."); \
}
Expand All @@ -124,7 +124,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"unlinkauth", types::unlinkauth{#account, #codeacct, messagetype}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Unlink " << #codeacct << "::" << messagetype << " from " << #account); \
}
#define LINKAUTH3(chain, account, codeacct) LINKAUTH5(chain, account, codeacct, "")
Expand All @@ -138,7 +138,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"transfer", types::transfer{#sender, #recipient, Amount.amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Transfered " << Amount << " from " << #sender << " to " << #recipient); \
}
#define XFER4(chain, sender, recipient, amount) XFER5(chain, sender, recipient, amount, "")
Expand All @@ -151,7 +151,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"lock", types::lock{#sender, #recipient, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Staked " << amount << " to " << #recipient); \
}
#define STAKE3(chain, account, amount) STAKE4(chain, account, account, amount)
Expand All @@ -165,7 +165,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"unlock", types::unlock{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Begin unstake " << amount << " to " << #account); \
}

Expand All @@ -177,7 +177,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"claim", types::claim{#account, amount}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Finish unstake " << amount << " to " << #account); \
}

Expand All @@ -190,7 +190,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"setproducer", types::setproducer{#owner, key, cfg}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Create producer " << #owner); \
}
#define MKPDCR3(chain, owner, key) MKPDCR4(chain, owner, key, BlockchainConfiguration{});
Expand All @@ -207,7 +207,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"okproducer", types::okproducer{#voter, #producer, approved? 1 : 0}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Set producer approval from " << #voter << " for " << #producer << " to " << approved); \
}

Expand All @@ -220,7 +220,7 @@ inline std::vector<Name> sort_names( std::vector<Name>&& names ) {
"setproducer", types::setproducer{owner, key, cfg}); \
trx.expiration = chain.head_block_time() + 100; \
trx.set_reference_block(chain.head_block_id()); \
chain.push_transaction(trx, chain_controller::skip_transaction_signatures); \
chain.push_transaction(trx); \
BOOST_TEST_CHECKPOINT("Update producer " << owner); \
}
#define UPPDCR3(chain, owner, key) UPPDCR4(chain, owner, key, chain.get_producer(owner).configuration)

0 comments on commit 7eb2013

Please sign in to comment.