Skip to content

Commit

Permalink
Merge branch 'release/1.0' into finality_violation_tests_1.0.0
Browse files Browse the repository at this point in the history
  • Loading branch information
systemzax authored Dec 28, 2024
2 parents 955aa87 + 790584e commit 241af18
Show file tree
Hide file tree
Showing 111 changed files with 4,713 additions and 1,356 deletions.
2 changes: 1 addition & 1 deletion .cicd/defaults.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"cdt":{
"target":"main",
"target":"4.1",
"prerelease":true
},
"referencecontracts":{
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,14 @@ jobs:
with:
name: ${{matrix.cfg.builddir}}-build
- name: Run Parallel Tests
env:
IS_SAN: ${{endsWith(matrix.cfg.name, 'san') && 'yes' || ''}}
run: |
# https://github.com/actions/runner/issues/2033 -- need this because of full version label test looking at git revs
chown -R $(id -u):$(id -g) $PWD
zstdcat build.tar.zst | tar x
cd build
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" --timeout 480
ctest --output-on-failure -j $(nproc) -LE "(nonparallelizable_tests|long_running_tests)" ${IS_SAN:+-E 'eos-vm$'} --timeout 480
- name: Upload core files from failed tests
uses: actions/upload-artifact@v4
if: failure()
Expand Down
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ set( CXX_STANDARD_REQUIRED ON)

set(VERSION_MAJOR 1)
set(VERSION_MINOR 0)
set(VERSION_PATCH 0)
set(VERSION_SUFFIX rc3)
set(VERSION_PATCH 3)
#set(VERSION_SUFFIX rc3)

if(VERSION_SUFFIX)
set(VERSION_FULL "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}-${VERSION_SUFFIX}")
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ nodeos --full-version
```
You should see a [semantic version](https://semver.org) string followed by a `git` commit hash with no errors. For example:
```
v3.1.2-0b64f879e3ebe2e4df09d2e62f1fc164cc1125d1
v1.0.1-9026a03c09c9b4f93edca696b5eef259f0ab96b3
```

## Build and Install from Source
Expand Down Expand Up @@ -84,7 +84,7 @@ cd spring
```

### Step 2 - Checkout Release Tag or Branch
Choose which [release](https://github.com/AntelopeIO/spring/releases) or [branch](#branches) you would like to build, then check it out. If you are not sure, use the [latest release](https://github.com/AntelopeIO/spring/releases/latest). For example, if you want to build release 3.1.2 then you would check it out using its tag, `v3.1.2`. In the example below, replace `v0.0.0` with your selected release tag accordingly:
Choose which [release](https://github.com/AntelopeIO/spring/releases) or [branch](#branches) you would like to build, then check it out. If you are not sure, use the [latest release](https://github.com/AntelopeIO/spring/releases/latest). For example, if you want to build release 1.0.1 then you would check it out using its tag, `v1.0.1`. In the example below, replace `v0.0.0` with your selected release tag accordingly:
```bash
git fetch --all --tags
git checkout v0.0.0
Expand Down
37 changes: 30 additions & 7 deletions libraries/chain/block_handle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,16 @@

namespace eosio::chain {

// -------------------------------------------------------------------------------------------
// prior to writing magic and version numbers, we simply serialized the class (*this) to
// file. Let's call this the implicit version 0, which is not supported anymore in
// Spring 1.0.1 and above.
// However, we need to make sure that `chain_head_magic` can't match the tag of a std::variant
// -------------------------------------------------------------------------------------------
constexpr uint64_t chain_head_magic = 0xf1f2f3f4f4f3f2f1;
constexpr uint64_t chain_head_version = 1;


void block_handle::write(const std::filesystem::path& state_file) {
if (!is_valid())
return;
Expand All @@ -13,24 +23,37 @@ void block_handle::write(const std::filesystem::path& state_file) {
fc::datastream<fc::cfile> f;
f.set_file_path(state_file);
f.open("wb");

fc::raw::pack(f, chain_head_magic);
fc::raw::pack(f, chain_head_version);
fc::raw::pack(f, *this);
}

bool block_handle::read(const std::filesystem::path& state_file) {
if (!std::filesystem::exists(state_file))
return false;

fc::datastream<fc::cfile> f;
f.set_file_path(state_file);
f.open("rb");
EOS_ASSERT(std::filesystem::file_size(state_file) >= 2 * sizeof(chain_head_magic), chain_exception,
"File `chain_head.dat` seems to be corrupted. The best course of action might be to restart from a snapshot" );

fc::raw::unpack(f, *this);
try {
fc::datastream<fc::cfile> f;
f.set_file_path(state_file);
f.open("rb");

ilog("Loading chain_head block ${bn} ${id}", ("bn", block_num())("id", id()));
uint64_t magic, version;
fc::raw::unpack(f, magic);
fc::raw::unpack(f, version);

std::filesystem::remove(state_file);
EOS_ASSERT(magic == chain_head_magic && version == chain_head_version, chain_exception,
"Error reading `chain_head.dat` file. It is likely a Spring 1.0.0 version which is not supported by Spring 1.0.1 and above. "
"The best course of action might be to restart from a snapshot" );

fc::raw::unpack(f, *this);
ilog("Loading chain_head block ${bn} ${id}", ("bn", block_num())("id", id()));
} FC_CAPTURE_AND_RETHROW( (state_file) );

// remove the `chain_head.dat` file only if we were able to successfully load it.
std::filesystem::remove(state_file);
return true;
}

Expand Down
80 changes: 78 additions & 2 deletions libraries/chain/block_header_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ digest_type block_header_state::compute_base_digest() const {
digest_type::encoder enc;

fc::raw::pack( enc, header );
fc::raw::pack( enc, core );
core.pack_for_digest( enc );

fc::raw::pack( enc, proposed_finalizer_policies );
fc::raw::pack( enc, pending_finalizer_policy );
Expand Down Expand Up @@ -107,7 +107,6 @@ const producer_authority& block_header_state::get_scheduled_producer(block_times

// returns producer using the proposer policy calculated by time `t`
const producer_authority& block_header_state::get_producer_for_block_at(block_timestamp_type next_block_timestamp) const {
assert(next_block_timestamp > timestamp()); // next block timestamp must be greater than current timestamp
return detail::get_scheduled_producer(get_active_proposer_policy_for_block_at(next_block_timestamp)->proposer_schedule.producers, next_block_timestamp);
}

Expand Down Expand Up @@ -141,6 +140,67 @@ const finalizer_policy& block_header_state::get_last_pending_finalizer_policy()
return *active_finalizer_policy;
}

// Only defined for core.latest_qc_claim().block_num <= ref.block_num() <= core.current_block_num()
// Retrieves the finalizer policies applicable for the block referenced by `ref`.
// See full explanation in issue #694.
// ------------------------------------------------------------------------------------------------
finalizer_policies_t block_header_state::get_finalizer_policies(const block_ref& ref) const {
assert(core.links.empty() || // called from a bogus block_state constructed in a test
(core.latest_qc_claim().block_num <= ref.block_num() && ref.block_num() <= core.current_block_num()));
finalizer_policies_t res;

res.finality_digest = ref.finality_digest;

auto active_gen = ref.active_policy_generation;
assert(active_gen != 0); // we should always have an active policy

if (active_finalizer_policy->generation == active_gen)
res.active_finalizer_policy = active_finalizer_policy; // the one active at block_num is still active
else {
// cannot be the pending one as it never was active
assert(!pending_finalizer_policy || pending_finalizer_policy->second->generation > active_gen);

// has to be the one in latest_qc_claim_block_active_finalizer_policy
assert(latest_qc_claim_block_active_finalizer_policy != nullptr);
assert(latest_qc_claim_block_active_finalizer_policy->generation == active_gen);
EOS_ASSERT(latest_qc_claim_block_active_finalizer_policy != nullptr &&
latest_qc_claim_block_active_finalizer_policy->generation == active_gen,
chain_exception,
"Logic error in finalizer policy retrieval"); // just in case
res.active_finalizer_policy = latest_qc_claim_block_active_finalizer_policy;
}

auto pending_gen = ref.pending_policy_generation;
if (pending_gen == 0)
res.pending_finalizer_policy = nullptr; // no pending policy at block_num.
else if (pending_gen == active_finalizer_policy->generation)
res.pending_finalizer_policy = active_finalizer_policy; // policy pending at block_num became active
else {
// cannot be the one in latest_qc_claim_block_active_finalizer_policy since it was active at
// core.latest_qc_claim().block_num. So it must be the one still pending.
assert(pending_finalizer_policy && pending_finalizer_policy->second->generation == pending_gen);
EOS_ASSERT(pending_finalizer_policy && pending_finalizer_policy->second->generation == pending_gen, chain_exception,
"Logic error in finalizer policy retrieval"); // just in case
res.pending_finalizer_policy = pending_finalizer_policy->second;
}

return res;
}

// Only defined for core.latest_qc_claim().block_num <= num <= core.current_block_num()
// Retrieves the active finalizer policy generation applicatble for the block `num`, which
// can be the current block or one of its ancestors up to core.latest_qc_claim().block_num (incl).
// -----------------------------------------------------------------------------------------------
uint32_t block_header_state::get_active_finalizer_policy_generation(block_num_type num) const {
assert(core.links.empty() || // called from a bogus block_state constructed in a test
(core.last_final_block_num() <= num && num <= core.current_block_num()));
if (num == block_num())
return active_finalizer_policy->generation;
const block_ref& ref = core.get_block_reference(num);
return ref.active_policy_generation;
}


// The last proposed proposer policy, if none proposed then the active proposer policy
const proposer_policy& block_header_state::get_last_proposed_proposer_policy() const {
if (latest_proposed_proposer_policy) {
Expand Down Expand Up @@ -325,6 +385,22 @@ void finish_next(const block_header_state& prev,
next_header_state.finalizer_policy_generation = prev.finalizer_policy_generation;
}

// now populate next_header_state.latest_qc_claim_block_active_finalizer_policy
// this keeps track of the finalizer policy which was active @ latest_qc_claim().block_num, but which
// can be overwritten by a previously pending policy (member `active_finalizer_policy`)
// See full explanation in issue #694.
// --------------------------------------------------------------------------------------------------
const auto& next_core = next_header_state.core;
auto latest_qc_claim_block_num = next_core.latest_qc_claim().block_num;
const auto active_generation_num = next_header_state.active_finalizer_policy->generation;
if (prev.get_active_finalizer_policy_generation(latest_qc_claim_block_num) != active_generation_num) {
const auto& latest_qc_claim_block_ref = next_header_state.core.get_block_reference(latest_qc_claim_block_num);
next_header_state.latest_qc_claim_block_active_finalizer_policy =
prev.get_finalizer_policies(latest_qc_claim_block_ref).active_finalizer_policy;
} else {
next_header_state.latest_qc_claim_block_active_finalizer_policy = nullptr;
}

// Finally update block id from header
// -----------------------------------
next_header_state.block_id = next_header_state.header.calculate_id();
Expand Down
Loading

0 comments on commit 241af18

Please sign in to comment.