Skip to content

Commit 491addc

Browse files
committed
Merge remote-tracking branch 'spring/main' into HEAD
2 parents b2ca768 + 52c236a commit 491addc

File tree

115 files changed

+3397
-1273
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+3397
-1273
lines changed

.cicd/defaults.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"cdt":{
3-
"target":"main",
3+
"target":"4.1",
44
"prerelease":true
55
},
66
"referencecontracts":{

.github/workflows/build.yaml

+6-2
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,14 @@ jobs:
151151
with:
152152
name: ${{matrix.cfg.builddir}}-build
153153
- name: Run Parallel Tests
154+
env:
155+
IS_SAN: ${{endsWith(matrix.cfg.name, 'san') && 'yes' || ''}}
154156
run: |
155157
# https://github.com/actions/runner/issues/2033 -- need this because of full version label test looking at git revs
156158
chown -R $(id -u):$(id -g) $PWD
157159
zstdcat build.tar.zst | tar x
158160
cd build
159-
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 480
161+
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" ${IS_SAN:+-E 'eos-vm$'} --timeout 480
160162
- name: Upload core files from failed tests
161163
uses: actions/upload-artifact@v4
162164
if: failure()
@@ -166,7 +168,9 @@ jobs:
166168
path: /cores
167169
compression-level: 0
168170
- name: Check CPU Features
169-
run: awk 'BEGIN {err = 1} /bmi2/ && /adx/ {err = 0} END {exit err}' /proc/cpuinfo
171+
run: |
172+
awk 'BEGIN {err = 1} /bmi2/ && /adx/ {err = 0} END {exit err}' /proc/cpuinfo
173+
build/tools/fsgsbase-enabled
170174
171175
np-tests:
172176
name: NP Tests (${{matrix.cfg.name}})

CMakeModules/VersionUtils.cmake

-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
cmake_minimum_required(VERSION 3.5)
2-
31
function(GENERATE_VERSION_METADATA)
42
# Execute `git` to grab the corresponding data.
53
execute_process(

libraries/chain/CMakeLists.txt

-5
Original file line numberDiff line numberDiff line change
@@ -163,11 +163,6 @@ foreach(RUNTIME ${EOSIO_WASM_RUNTIMES})
163163
target_compile_definitions(eosio_chain PUBLIC "EOSIO_${RUNTIMEUC}_RUNTIME_ENABLED")
164164
endforeach()
165165

166-
if(EOSVMOC_ENABLE_DEVELOPER_OPTIONS)
167-
message(WARNING "EOS VM OC Developer Options are enabled; these are NOT supported")
168-
target_compile_definitions(eosio_chain PUBLIC EOSIO_EOS_VM_OC_DEVELOPER)
169-
endif()
170-
171166
install( TARGETS eosio_chain
172167
RUNTIME DESTINATION ${CMAKE_INSTALL_FULL_BINDIR} COMPONENT dev EXCLUDE_FROM_ALL
173168
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR} COMPONENT dev EXCLUDE_FROM_ALL

libraries/chain/apply_context.cpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -1090,16 +1090,21 @@ action_name apply_context::get_sender() const {
10901090
return action_name();
10911091
}
10921092

1093+
bool apply_context::is_eos_vm_oc_whitelisted() const {
1094+
return receiver.prefix() == config::system_account_name || // "eosio"_n
1095+
control.is_eos_vm_oc_whitelisted(receiver);
1096+
}
1097+
10931098
// Context | OC?
10941099
//-------------------------------------------------------------------------------
1095-
// Building block | baseline, OC for eosio.*
1096-
// Applying block | OC unless a producer, OC for eosio.* including producers
1097-
// Speculative API trx | baseline, OC for eosio.*
1098-
// Speculative P2P trx | baseline, OC for eosio.*
1099-
// Compute trx | baseline, OC for eosio.*
1100+
// Building block | baseline, OC for whitelisted
1101+
// Applying block | OC unless a producer, OC for whitelisted including producers
1102+
// Speculative API trx | baseline, OC for whitelisted
1103+
// Speculative P2P trx | baseline, OC for whitelisted
1104+
// Compute trx | baseline, OC for whitelisted
11001105
// Read only trx | OC
11011106
bool apply_context::should_use_eos_vm_oc()const {
1102-
return receiver.prefix() == config::system_account_name // "eosio"_n, all cases use OC
1107+
return is_eos_vm_oc_whitelisted() // all whitelisted accounts use OC always
11031108
|| (is_applying_block() && !control.is_producer_node()) // validating/applying block
11041109
|| trx_context.is_read_only();
11051110
}

libraries/chain/controller.cpp

+145-117
Large diffs are not rendered by default.

libraries/chain/fork_database.cpp

+20-9
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ namespace eosio::chain {
9494

9595
void open_impl( const char* desc, const std::filesystem::path& fork_db_file, fc::cfile_datastream& ds, validator_t& validator );
9696
void close_impl( std::ofstream& out );
97-
bool add_impl( const bsp_t& n, ignore_duplicate_t ignore_duplicate, bool validate, validator_t& validator );
97+
fork_db_add_t add_impl( const bsp_t& n, ignore_duplicate_t ignore_duplicate, bool validate, validator_t& validator );
9898
bool is_valid() const;
9999

100100
bsp_t get_block_impl( const block_id_type& id, include_root_t include_root = include_root_t::no ) const;
@@ -192,10 +192,11 @@ namespace eosio::chain {
192192

193193
template<class BSP>
194194
void fork_database_impl<BSP>::reset_root_impl( const bsp_t& root_bsp ) {
195-
index.clear();
196195
assert(root_bsp);
197196
root = root_bsp;
198197
root->set_valid(true);
198+
pending_savanna_lib_id = block_id_type{};
199+
index.clear();
199200
}
200201

201202
template<class BSP>
@@ -240,8 +241,8 @@ namespace eosio::chain {
240241
}
241242

242243
template <class BSP>
243-
bool fork_database_impl<BSP>::add_impl(const bsp_t& n, ignore_duplicate_t ignore_duplicate,
244-
bool validate, validator_t& validator) {
244+
fork_db_add_t fork_database_impl<BSP>::add_impl(const bsp_t& n, ignore_duplicate_t ignore_duplicate,
245+
bool validate, validator_t& validator) {
245246
EOS_ASSERT( root, fork_database_exception, "root not yet set" );
246247
EOS_ASSERT( n, fork_database_exception, "attempt to add null block state" );
247248

@@ -277,15 +278,25 @@ namespace eosio::chain {
277278
EOS_RETHROW_EXCEPTIONS( fork_database_exception, "serialized fork database is incompatible with configured protocol features" )
278279
}
279280

281+
auto prev_head = head_impl(include_root_t::yes);
282+
280283
auto inserted = index.insert(n);
281284
EOS_ASSERT(ignore_duplicate == ignore_duplicate_t::yes || inserted.second, fork_database_exception,
282285
"duplicate block added: ${id}", ("id", n->id()));
283286

284-
return inserted.second && n == head_impl(include_root_t::no);
287+
if (!inserted.second)
288+
return fork_db_add_t::duplicate;
289+
const bool new_head = n == head_impl(include_root_t::no);
290+
if (new_head && n->previous() == prev_head->id())
291+
return fork_db_add_t::appended_to_head;
292+
if (new_head)
293+
return fork_db_add_t::fork_switch;
294+
295+
return fork_db_add_t::added;
285296
}
286297

287298
template<class BSP>
288-
bool fork_database_t<BSP>::add( const bsp_t& n, ignore_duplicate_t ignore_duplicate ) {
299+
fork_db_add_t fork_database_t<BSP>::add( const bsp_t& n, ignore_duplicate_t ignore_duplicate ) {
289300
std::lock_guard g( my->mtx );
290301
return my->add_impl(n, ignore_duplicate, false,
291302
[](block_timestamp_type timestamp,
@@ -448,8 +459,8 @@ namespace eosio::chain {
448459
BSP fork_database_impl<BSP>::search_on_branch_impl( const block_id_type& h, uint32_t block_num, include_root_t include_root ) const {
449460
if (!root)
450461
return {};
451-
if( include_root == include_root_t::yes && root->id() == h && root->block_num() == block_num ) {
452-
return root;
462+
if( include_root == include_root_t::yes && root->block_num() == block_num ) {
463+
return root; // root is root of every branch, no need to check h
453464
}
454465
if (block_num <= root->block_num())
455466
return {};
@@ -582,7 +593,7 @@ namespace eosio::chain {
582593
template<class BSP>
583594
BSP fork_database_impl<BSP>::get_block_impl(const block_id_type& id,
584595
include_root_t include_root /* = include_root_t::no */) const {
585-
if( include_root == include_root_t::yes && root->id() == id ) {
596+
if( include_root == include_root_t::yes && root && root->id() == id ) {
586597
return root;
587598
}
588599
auto itr = index.find( id );

libraries/chain/include/eosio/chain/apply_context.hpp

+1
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,7 @@ class apply_context {
601601
action_name get_sender() const;
602602

603603
bool is_applying_block() const { return trx_context.explicit_billed_cpu_time; }
604+
bool is_eos_vm_oc_whitelisted() const;
604605
bool should_use_eos_vm_oc()const;
605606

606607
/// Fields:

libraries/chain/include/eosio/chain/controller.hpp

+14-6
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ namespace eosio::chain {
9696
using resource_limits::resource_limits_manager;
9797
using apply_handler = std::function<void(apply_context&)>;
9898

99+
enum class fork_db_add_t;
99100
using forked_callback_t = std::function<void(const transaction_metadata_ptr&)>;
100101

101102
// lookup transaction_metadata via supplied function to avoid re-creation
@@ -155,6 +156,7 @@ namespace eosio::chain {
155156
wasm_interface::vm_type wasm_runtime = chain::config::default_wasm_runtime;
156157
eosvmoc::config eosvmoc_config;
157158
wasm_interface::vm_oc_enable eosvmoc_tierup = wasm_interface::vm_oc_enable::oc_auto;
159+
flat_set<account_name> eos_vm_oc_whitelist_suffixes;
158160

159161
db_read_mode read_mode = db_read_mode::HEAD;
160162
validation_mode block_validation_mode = validation_mode::FULL;
@@ -206,8 +208,8 @@ namespace eosio::chain {
206208
*/
207209
deque<transaction_metadata_ptr> abort_block();
208210

209-
/// Expected to be called from signal handler
210-
void interrupt_transaction();
211+
/// Expected to be called from signal handler, or producer_plugin
212+
void interrupt_apply_block_transaction();
211213

212214
/**
213215
*
@@ -234,16 +236,17 @@ namespace eosio::chain {
234236
void set_async_aggregation(async_t val);
235237

236238
struct accepted_block_result {
237-
const bool is_new_best_head = false; // true if new best head
239+
const fork_db_add_t add_result;
238240
std::optional<block_handle> block; // empty optional if block is unlinkable
239241
};
240242
// thread-safe
241243
accepted_block_result accept_block( const block_id_type& id, const signed_block_ptr& b ) const;
242244

243245
/// Apply any blocks that are ready from the fork_db
244246
enum class apply_blocks_result {
245-
complete, // all ready blocks in forkdb have been applied
246-
incomplete // time limit reached, additional blocks may be available in forkdb to process
247+
complete, // all ready blocks in forkdb have been applied
248+
incomplete, // time limit reached, additional blocks may be available in forkdb to process
249+
paused // apply blocks currently paused
247250
};
248251
apply_blocks_result apply_blocks(const forked_callback_t& cb, const trx_meta_cache_lookup& trx_lookup);
249252

@@ -420,6 +423,8 @@ namespace eosio::chain {
420423

421424
bool is_profiling(account_name name) const;
422425

426+
bool is_eos_vm_oc_whitelisted(const account_name& n) const;
427+
423428
chain_id_type get_chain_id()const;
424429

425430
// thread safe
@@ -473,7 +478,10 @@ namespace eosio::chain {
473478
void replace_account_keys( name account, name permission, const public_key_type& key );
474479

475480
void set_producer_node(bool is_producer_node);
476-
bool is_producer_node()const;
481+
bool is_producer_node()const; // thread safe, set at program initialization
482+
483+
void set_pause_at_block_num(block_num_type block_num);
484+
block_num_type get_pause_at_block_num()const;
477485

478486
void set_db_read_only_mode();
479487
void unset_db_read_only_mode();

libraries/chain/include/eosio/chain/exceptions.hpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -141,10 +141,6 @@
141141
\
142142
virtual std::shared_ptr<fc::exception> dynamic_copy_exception()const\
143143
{ return std::make_shared<TYPE>( *this ); } \
144-
virtual NO_RETURN void dynamic_rethrow_exception()const \
145-
{ if( code() == CODE ) throw *this;\
146-
else fc::exception::dynamic_rethrow_exception(); \
147-
} \
148144
std::optional<uint64_t> error_code; \
149145
};
150146

@@ -394,6 +390,8 @@ namespace eosio { namespace chain {
394390
3080010, "Read-only transaction eos-vm-oc compile permanent failure" )
395391
FC_DECLARE_DERIVED_EXCEPTION( interrupt_exception, resource_exhausted_exception,
396392
3080011, "Transaction interrupted by signal" )
393+
FC_DECLARE_DERIVED_EXCEPTION( interrupt_oc_exception, resource_exhausted_exception,
394+
3080012, "Transaction interrupted by oc compile" )
397395

398396
FC_DECLARE_DERIVED_EXCEPTION( authorization_exception, chain_exception,
399397
3090000, "Authorization exception" )
@@ -611,6 +609,8 @@ namespace eosio { namespace chain {
611609
3170015, "Invalid snapshot request" )
612610
FC_DECLARE_DERIVED_EXCEPTION( snapshot_execution_exception, producer_exception,
613611
3170016, "Snapshot execution exception" )
612+
FC_DECLARE_DERIVED_EXCEPTION( invalid_pause_at_block_request, producer_exception,
613+
3170017, "Invalid pause at block request" )
614614

615615
FC_DECLARE_DERIVED_EXCEPTION( reversible_blocks_exception, chain_exception,
616616
3180000, "Reversible Blocks exception" )

libraries/chain/include/eosio/chain/fork_database.hpp

+14-2
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,13 @@ namespace eosio::chain {
1212
using block_branch_t = std::vector<signed_block_ptr>;
1313
enum class ignore_duplicate_t { no, yes };
1414
enum class include_root_t { no, yes };
15+
enum class fork_db_add_t {
16+
failure, // add failed
17+
duplicate, // already added and ignore_duplicate=true
18+
added, // inserted into an existing branch or started a new branch, but not best branch
19+
appended_to_head, // new best head of current best branch; no fork switch
20+
fork_switch // new best head of new branch, fork switch to new branch
21+
};
1522

1623
// Used for logging of comparison values used for best fork determination
1724
std::string log_fork_comparison(const block_state& bs);
@@ -67,9 +74,11 @@ namespace eosio::chain {
6774
/**
6875
* Add block state to fork database.
6976
* Must link to existing block in fork database or the root.
70-
* @return true if n becomes the new best head (and was not the best head before)
77+
* @returns fork_db_add_t - result of the add
78+
* @throws unlinkable_block_exception - unlinkable to any branch
79+
* @throws fork_database_exception - no root, n is nullptr, protocol feature error, duplicate when ignore_duplicate=false
7180
*/
72-
bool add( const bsp_t& n, ignore_duplicate_t ignore_duplicate );
81+
fork_db_add_t add( const bsp_t& n, ignore_duplicate_t ignore_duplicate );
7382

7483
void remove( const block_id_type& id );
7584

@@ -306,3 +315,6 @@ namespace eosio::chain {
306315
static constexpr uint32_t max_supported_version = 3;
307316
};
308317
} /// eosio::chain
318+
319+
FC_REFLECT_ENUM( eosio::chain::fork_db_add_t,
320+
(failure)(duplicate)(added)(appended_to_head)(fork_switch) )

libraries/chain/include/eosio/chain/name.hpp

+38
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,44 @@ namespace eosio::chain {
110110

111111
return name{ result };
112112
}
113+
114+
/**
115+
* Returns the suffix.
116+
* for example:
117+
* "eosio.any" -> "any"
118+
* "eosio" -> "eosio"
119+
*/
120+
constexpr name suffix() const {
121+
uint32_t remaining_bits_after_last_actual_dot = 0;
122+
uint32_t tmp = 0;
123+
for (int32_t remaining_bits = 59; remaining_bits >= 4; remaining_bits -= 5) { // Note: remaining_bits must remain signed integer
124+
// Get characters one-by-one in name in order from left to right (not including the 13th character)
125+
auto c = (value >> remaining_bits) & 0x1Full;
126+
if (!c) { // if this character is a dot
127+
tmp = static_cast<uint32_t>(remaining_bits);
128+
} else { // if this character is not a dot
129+
remaining_bits_after_last_actual_dot = tmp;
130+
}
131+
}
132+
133+
uint64_t thirteenth_character = value & 0x0Full;
134+
if (thirteenth_character) { // if 13th character is not a dot
135+
remaining_bits_after_last_actual_dot = tmp;
136+
}
137+
138+
if (remaining_bits_after_last_actual_dot == 0) // there is no actual dot in the %name other than potentially leading dots
139+
return name{ value };
140+
141+
// At this point remaining_bits_after_last_actual_dot has to be within the range of 4 to 59 (and restricted to
142+
// increments of 5).
143+
144+
// Mask for remaining bits corresponding to characters after last actual dot, except for 4 least significant bits
145+
// (corresponds to 13th character).
146+
uint64_t mask = (1ull << remaining_bits_after_last_actual_dot) - 16;
147+
uint32_t shift = 64 - remaining_bits_after_last_actual_dot;
148+
149+
return name{ ((value & mask) << shift) + (thirteenth_character << (shift - 1)) };
150+
}
113151
};
114152

115153
// Each char of the string is encoded into 5-bit chunk and left-shifted

0 commit comments

Comments
 (0)