Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/hotstuff_integration' into GH-2057
Browse files Browse the repository at this point in the history
…-transition
  • Loading branch information
heifner committed Mar 26, 2024
2 parents 1056702 + 1b0a63b commit 86a0b28
Show file tree
Hide file tree
Showing 22 changed files with 1,379 additions and 101 deletions.
3 changes: 2 additions & 1 deletion benchmark/bls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ struct interface_in_benchmark {
// build transaction context from the packed transaction
timer = std::make_unique<platform_timer>();
trx_timer = std::make_unique<transaction_checktime_timer>(*timer);
trx_ctx = std::make_unique<transaction_context>(*chain->control.get(), *ptrx, ptrx->id(), std::move(*trx_timer));
trx_ctx = std::make_unique<transaction_context>(*chain->control.get(), *ptrx, ptrx->id(), std::move(*trx_timer),
action_digests_t::store_which_t::legacy);
trx_ctx->max_transaction_time_subjective = fc::microseconds::maximum();
trx_ctx->init_for_input_trx( ptrx->get_unprunable_size(), ptrx->get_prunable_size() );
trx_ctx->exec(); // this is required to generate action traces to be used by apply_context constructor
Expand Down
20 changes: 10 additions & 10 deletions libraries/chain/apply_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

using boost::container::flat_set;

namespace eosio { namespace chain {
namespace eosio::chain {

static inline void print_debug(account_name receiver, const action_trace& ar) {
if (!ar.console.empty()) {
Expand Down Expand Up @@ -184,7 +184,7 @@ void apply_context::exec_one()
r.auth_sequence[auth.actor] = next_auth_sequence( auth.actor );
}

trx_context.executed_action_receipt_digests.emplace_back( r.digest() );
trx_context.executed_action_receipts.compute_and_append_digests_from(trace);

finalize_trace( trace, start );

Expand Down Expand Up @@ -218,17 +218,17 @@ void apply_context::exec()
exec_one();
}

if( _cfa_inline_actions.size() > 0 || _inline_actions.size() > 0 ) {
if( !_cfa_inline_actions.empty() || !_inline_actions.empty() ) {
EOS_ASSERT( recurse_depth < control.get_global_properties().configuration.max_inline_action_depth,
transaction_exception, "max inline action depth per transaction reached" );
}

for( uint32_t ordinal : _cfa_inline_actions ) {
trx_context.execute_action( ordinal, recurse_depth + 1 );
}
for( uint32_t ordinal : _cfa_inline_actions ) {
trx_context.execute_action( ordinal, recurse_depth + 1 );
}

for( uint32_t ordinal : _inline_actions ) {
trx_context.execute_action( ordinal, recurse_depth + 1 );
for( uint32_t ordinal : _inline_actions ) {
trx_context.execute_action( ordinal, recurse_depth + 1 );
}
}

} /// exec()
Expand Down Expand Up @@ -1105,4 +1105,4 @@ bool apply_context::should_use_eos_vm_oc()const {
}


} } /// eosio::chain
} /// eosio::chain
2 changes: 1 addition & 1 deletion libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ block_header_state block_header_state::next(block_header_state_input& input) con
// header
// ------
next_header_state.header = {
.timestamp = input.timestamp, // [greg todo] do we have to do the slot++ stuff from the legacy version?
.timestamp = input.timestamp,
.producer = input.producer,
.confirmed = 0,
.previous = input.parent_id,
Expand Down
120 changes: 70 additions & 50 deletions libraries/chain/controller.cpp

Large diffs are not rendered by default.

17 changes: 3 additions & 14 deletions libraries/chain/include/eosio/chain/action_receipt.hpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
#pragma once

#include <eosio/chain/types.hpp>
#include <eosio/chain/action.hpp>

namespace eosio { namespace chain {
namespace eosio::chain {

/**
* For each action dispatched this receipt is generated
Expand All @@ -15,20 +16,8 @@ namespace eosio { namespace chain {
flat_map<account_name,uint64_t> auth_sequence;
fc::unsigned_int code_sequence = 0; ///< total number of setcodes
fc::unsigned_int abi_sequence = 0; ///< total number of setabis

digest_type digest()const {
digest_type::encoder e;
fc::raw::pack(e, receiver);
fc::raw::pack(e, act_digest);
fc::raw::pack(e, global_sequence);
fc::raw::pack(e, recv_sequence);
fc::raw::pack(e, auth_sequence);
fc::raw::pack(e, code_sequence);
fc::raw::pack(e, abi_sequence);
return e.result();
}
};

} } /// namespace eosio::chain
} /// namespace eosio::chain

FC_REFLECT( eosio::chain::action_receipt, (receiver)(act_digest)(global_sequence)(recv_sequence)(auth_sequence)(code_sequence)(abi_sequence) )
4 changes: 2 additions & 2 deletions libraries/chain/include/eosio/chain/incremental_merkle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ constexpr int clz_power_2(uint64_t value) {
* @param node_count - the number of nodes in the implied tree
* @return the max depth of the minimal tree that stores them
*/
constexpr int calcluate_max_depth(uint64_t node_count) {
constexpr int calculate_max_depth(uint64_t node_count) {
if (node_count == 0) {
return 0;
}
Expand Down Expand Up @@ -166,7 +166,7 @@ class incremental_merkle_impl {
*/
const DigestType& append(const DigestType& digest) {
bool partial = false;
auto max_depth = detail::calcluate_max_depth(_node_count + 1);
auto max_depth = detail::calculate_max_depth(_node_count + 1);
auto current_depth = max_depth - 1;
auto index = _node_count;
auto top = digest;
Expand Down
4 changes: 2 additions & 2 deletions libraries/chain/include/eosio/chain/merkle.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@ namespace eosio { namespace chain {
* Uses make_canonical_pair which before hashing sets the first bit of the previous hashes
* to 0 or 1 to indicate the side it is on.
*/
digest_type legacy_merkle( deque<digest_type> ids );
digest_type legacy_merkle( deque<digest_type>&& ids );

/**
* Calculates the merkle root of a set of digests. Does not manipulate the digests.
*/
digest_type calculate_merkle( deque<digest_type> ids );
digest_type calculate_merkle( deque<digest_type>&& ids );

} } /// eosio::chain
41 changes: 39 additions & 2 deletions libraries/chain/include/eosio/chain/trace.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <eosio/chain/action_receipt.hpp>
#include <eosio/chain/block.hpp>

namespace eosio { namespace chain {
namespace eosio::chain {

struct account_delta {
account_delta( const account_name& n, int64_t d):account(n),delta(d){}
Expand Down Expand Up @@ -45,6 +45,43 @@ namespace eosio { namespace chain {
std::optional<fc::exception> except;
std::optional<uint64_t> error_code;
std::vector<char> return_value;

digest_type digest_savanna() const {
assert(!!receipt);
const action_receipt& r = *receipt;

digest_type::encoder e;
fc::raw::pack(e, r.receiver);
fc::raw::pack(e, r.recv_sequence);
fc::raw::pack(e, act.account);
fc::raw::pack(e, act.name);
fc::raw::pack(e, r.act_digest);

{
digest_type::encoder e2;
fc::raw::pack(e2, r.global_sequence);
fc::raw::pack(e2, r.auth_sequence);
fc::raw::pack(e2, r.code_sequence);
fc::raw::pack(e2, r.abi_sequence);
fc::raw::pack(e, e2.result());
}
return e.result();
}

digest_type digest_legacy()const {
assert(!!receipt);
const action_receipt& r = *receipt;

digest_type::encoder e;
fc::raw::pack(e, r.receiver);
fc::raw::pack(e, r.act_digest);
fc::raw::pack(e, r.global_sequence);
fc::raw::pack(e, r.recv_sequence);
fc::raw::pack(e, r.auth_sequence);
fc::raw::pack(e, r.code_sequence);
fc::raw::pack(e, r.abi_sequence);
return e.result();
}
};

struct transaction_trace {
Expand Down Expand Up @@ -80,7 +117,7 @@ namespace eosio { namespace chain {
auth.permission == eosio::chain::config::active_name;
}

} } /// namespace eosio::chain
} /// namespace eosio::chain

FC_REFLECT( eosio::chain::account_delta,
(account)(delta) )
Expand Down
50 changes: 48 additions & 2 deletions libraries/chain/include/eosio/chain/transaction_context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,52 @@ namespace eosio { namespace chain {
friend controller_impl;
};

struct action_digests_t {
enum class store_which_t { legacy, savanna, both };

std::optional<digests_t> digests_l; // legacy
std::optional<digests_t> digests_s; // savanna

action_digests_t(store_which_t sw) {
if (sw == store_which_t::legacy || sw == store_which_t::both)
digests_l = digests_t{};
if (sw == store_which_t::savanna || sw == store_which_t::both)
digests_s = digests_t{};
}

void append(action_digests_t&& o) {
if (digests_l)
fc::move_append(*digests_l, std::move(*o.digests_l));
if (digests_s)
fc::move_append(*digests_s, std::move(*o.digests_s));
}

void compute_and_append_digests_from(action_trace& trace) {
if (digests_l)
digests_l->emplace_back(trace.digest_legacy());
if (digests_s)
digests_s->emplace_back(trace.digest_savanna());
}

store_which_t store_which() const {
if (digests_l && digests_s)
return store_which_t::both;
if (digests_l)
return store_which_t::legacy;
assert(digests_s);
return store_which_t::savanna;
}

std::pair<size_t, size_t> size() const {
return { digests_l ? digests_l->size() : 0, digests_s ? digests_s->size() : 0 };
}

void resize(std::pair<size_t, size_t> sz) {
if (digests_l) digests_l->resize(sz.first);
if (digests_s) digests_s->resize(sz.second);
}
};

class transaction_context {
private:
void init( uint64_t initial_net_usage);
Expand All @@ -43,6 +89,7 @@ namespace eosio { namespace chain {
const packed_transaction& t,
const transaction_id_type& trx_id, // trx_id diff than t.id() before replace_deferred
transaction_checktime_timer&& timer,
action_digests_t::store_which_t sad,
fc::time_point start = fc::time_point::now(),
transaction_metadata::trx_type type = transaction_metadata::trx_type::input);
~transaction_context();
Expand Down Expand Up @@ -140,8 +187,7 @@ namespace eosio { namespace chain {

fc::time_point published;


deque<digest_type> executed_action_receipt_digests;
action_digests_t executed_action_receipts;
flat_set<account_name> bill_to_accounts;
flat_set<account_name> validate_ram_usage;

Expand Down
4 changes: 2 additions & 2 deletions libraries/chain/merkle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ bool is_canonical_right(const digest_type& val) {
}


digest_type legacy_merkle(deque<digest_type> ids) {
digest_type legacy_merkle(deque<digest_type>&& ids) {
if( 0 == ids.size() ) { return digest_type(); }

while( ids.size() > 1 ) {
Expand All @@ -49,7 +49,7 @@ digest_type legacy_merkle(deque<digest_type> ids) {
return ids.front();
}

digest_type calculate_merkle( deque<digest_type> ids ) {
digest_type calculate_merkle( deque<digest_type>&& ids ) {
if( 0 == ids.size() ) { return digest_type(); }

while( ids.size() > 1 ) {
Expand Down
6 changes: 4 additions & 2 deletions libraries/chain/transaction_context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

#include <chrono>

namespace eosio { namespace chain {
namespace eosio::chain {

transaction_checktime_timer::transaction_checktime_timer(platform_timer& timer)
: expired(timer.expired), _timer(timer) {
Expand Down Expand Up @@ -39,6 +39,7 @@ namespace eosio { namespace chain {
const packed_transaction& t,
const transaction_id_type& trx_id,
transaction_checktime_timer&& tmr,
action_digests_t::store_which_t store_which,
fc::time_point s,
transaction_metadata::trx_type type)
:control(c)
Expand All @@ -47,6 +48,7 @@ namespace eosio { namespace chain {
,undo_session()
,trace(std::make_shared<transaction_trace>())
,start(s)
,executed_action_receipts(store_which)
,transaction_timer(std::move(tmr))
,trx_type(type)
,net_usage(trace->net_usage)
Expand Down Expand Up @@ -828,4 +830,4 @@ namespace eosio { namespace chain {
}


} } /// eosio::chain
} /// eosio::chain
15 changes: 8 additions & 7 deletions unittests/api_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -907,16 +907,17 @@ BOOST_AUTO_TEST_CASE(light_validation_skip_cfa) try {
BOOST_CHECK(*trace->receipt == *other_trace->receipt);
BOOST_CHECK_EQUAL(2, other_trace->action_traces.size());

auto check_action_traces = [](const auto& t, const auto& ot) {
BOOST_CHECK_EQUAL("", ot.console); // cfa not executed for light validation (trusted producer)
BOOST_CHECK_EQUAL(t.receipt->global_sequence, ot.receipt->global_sequence);
BOOST_CHECK_EQUAL(t.digest_legacy(), ot.digest_legacy()); // digest_legacy because test doesn't switch to Savanna
};

BOOST_CHECK(other_trace->action_traces.at(0).context_free); // cfa
BOOST_CHECK_EQUAL("", other_trace->action_traces.at(0).console); // cfa not executed for light validation (trusted producer)
BOOST_CHECK_EQUAL(trace->action_traces.at(0).receipt->global_sequence, other_trace->action_traces.at(0).receipt->global_sequence);
BOOST_CHECK_EQUAL(trace->action_traces.at(0).receipt->digest(), other_trace->action_traces.at(0).receipt->digest());
check_action_traces(trace->action_traces.at(0), other_trace->action_traces.at(0));

BOOST_CHECK(!other_trace->action_traces.at(1).context_free); // non-cfa
BOOST_CHECK_EQUAL("", other_trace->action_traces.at(1).console);
BOOST_CHECK_EQUAL(trace->action_traces.at(1).receipt->global_sequence, other_trace->action_traces.at(1).receipt->global_sequence);
BOOST_CHECK_EQUAL(trace->action_traces.at(1).receipt->digest(), other_trace->action_traces.at(1).receipt->digest());

check_action_traces(trace->action_traces.at(1), other_trace->action_traces.at(1));

other.close();

Expand Down
14 changes: 8 additions & 6 deletions unittests/restart_chain_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,15 +226,17 @@ BOOST_AUTO_TEST_CASE(test_light_validation_restart_from_block_log) {
BOOST_CHECK(*trace->receipt == *other_trace->receipt);
BOOST_CHECK_EQUAL(2u, other_trace->action_traces.size());

auto check_action_traces = [](const auto& t, const auto& ot) {
BOOST_CHECK_EQUAL("", ot.console); // cfa not executed for replay
BOOST_CHECK_EQUAL(t.receipt->global_sequence, ot.receipt->global_sequence);
BOOST_CHECK_EQUAL(t.digest_legacy(), ot.digest_legacy()); // digest_legacy because test doesn't switch to Savanna
};

BOOST_CHECK(other_trace->action_traces.at(0).context_free); // cfa
BOOST_CHECK_EQUAL("", other_trace->action_traces.at(0).console); // cfa not executed for replay
BOOST_CHECK_EQUAL(trace->action_traces.at(0).receipt->global_sequence, other_trace->action_traces.at(0).receipt->global_sequence);
BOOST_CHECK_EQUAL(trace->action_traces.at(0).receipt->digest(), other_trace->action_traces.at(0).receipt->digest());
check_action_traces(trace->action_traces.at(0), other_trace->action_traces.at(0));

BOOST_CHECK(!other_trace->action_traces.at(1).context_free); // non-cfa
BOOST_CHECK_EQUAL("", other_trace->action_traces.at(1).console);
BOOST_CHECK_EQUAL(trace->action_traces.at(1).receipt->global_sequence, other_trace->action_traces.at(1).receipt->global_sequence);
BOOST_CHECK_EQUAL(trace->action_traces.at(1).receipt->digest(), other_trace->action_traces.at(1).receipt->digest());
check_action_traces(trace->action_traces.at(1), other_trace->action_traces.at(1));
}

BOOST_AUTO_TEST_SUITE_END()
Loading

0 comments on commit 86a0b28

Please sign in to comment.