Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 69 additions & 16 deletions .github/workflows/ubuntu-2204.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,25 +6,78 @@ on:
- "release/*"
pull_request:
types: [assigned, opened, synchronize, reopened, labeled]
workflow_dispatch:
env:
BUILDER_IMAGE: "apm2006/leap:v3.2.5-cdt4.0.1"
CDT_VERSION: "4.1.1"
CDT_DEB_SHA256: "d946e6b64f297442d19e486401aa49f956080b07a1fa6335f29976106175b588"
# Commit SHA of tag teloszero-v1.2.2 (tags are mutable; pin the commit)
TELOSZERO_REF: "fcb9f5fc627619a8b06cd6b871c462b1d70d3aa4"
EXPECTED_EOSIO_SYSTEM_ABI_SHA256: "5545f53b6b2e407acb45c6d14e283866c451d8e47c567baeb74284a55c93c9e1"
EXPECTED_EOSIO_SYSTEM_WASM_SHA256: "c4dc8dad19768a7ac3bc3519111c6ea632faf9a829eae9366fcb51bba94969f4"
jobs:
ubuntu-2404-build:
name: Ubuntu 22.04 | Build
runs-on: ubuntu-latest
ubuntu-2204-build:
name: Ubuntu 22.04 | Spring/Telos Zero build
runs-on: ubuntu-22.04
container: apm2006/leap:v3.2.5-cdt4.0.1
defaults:
run:
shell: bash
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Build
- name: Checkout TelosZero Core
uses: actions/checkout@v4
with:
repository: TelosNetwork/teloszero-core
ref: ${{ env.TELOSZERO_REF }}
path: spring-src
submodules: recursive
- name: Install CDT
run: |
set -euo pipefail
cdt_deb="/tmp/cdt_${CDT_VERSION}-1_amd64.deb"
curl -L --retry 3 --fail \
"https://github.com/AntelopeIO/cdt/releases/download/v${CDT_VERSION}/cdt_${CDT_VERSION}-1_amd64.deb" \
-o "${cdt_deb}"
echo "${CDT_DEB_SHA256} ${cdt_deb}" | sha256sum -c -
dpkg -i "${cdt_deb}"
cdt-cpp --version | grep "${CDT_VERSION}"
test -f "/usr/opt/cdt/${CDT_VERSION}/include/eosiolib/contracts/eosio/instant_finality.hpp"
test -f "/usr/opt/cdt/${CDT_VERSION}/include/eosiolib/core/eosio/crypto_bls_ext.hpp"
- name: Build TelosZero tester libraries
run: |
set -euo pipefail
cmake -S spring-src -B spring-build -DCMAKE_BUILD_TYPE=Release
cmake --build spring-build --target eosio_testing -- -j "$(nproc)"
test -f spring-build/libraries/testing/libeosio_testing.a
test -d spring-build/lib/cmake/leap
- name: Build contracts
run: |
set -euo pipefail
cmake -S . -B build \
-DCMAKE_BUILD_TYPE=Release \
-DBUILD_TESTS=yes \
-Dleap_DIR="${PWD}/spring-build/lib/cmake/leap"
cmake --build build -- -j "$(nproc)" VERBOSE=1
- name: Test
run: |
set -euo pipefail
ctest --test-dir build/tests --output-on-failure -j "$(nproc)"
- name: Report build artifact hashes
run: |
set -euo pipefail
abi_hash="$(sha256sum build/contracts/eosio.system/eosio.system.abi | awk '{print $1}')"
wasm_hash="$(sha256sum build/contracts/eosio.system/eosio.system.wasm | awk '{print $1}')"
echo "eosio.system.abi ${abi_hash}"
echo "eosio.system.wasm ${wasm_hash}"
# Only enforce the expected release hashes on manually-dispatched runs
# and release branches. Asserting on every PR would fail CI for any
# legitimate contract change until the expected hashes are updated.
- name: Assert release artifact hashes
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/heads/release/')
run: |
set -e
export DOCKER="docker run --rm -v $(pwd):/root/target ${BUILDER_IMAGE}"
docker pull ${BUILDER_IMAGE}
echo ${DOCKER}
echo =====
mkdir build
${DOCKER} bash -c "cd build && cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=yes -Dleap_DIR=/opt/leap/build/lib/cmake/leap .."
echo =====
${DOCKER} bash -c "cd build && make -j $(nproc) VERBOSE=1"
echo =====
${DOCKER} bash -c 'cd build/tests && ctest -j $(nproc)'
set -euo pipefail
abi_hash="$(sha256sum build/contracts/eosio.system/eosio.system.abi | awk '{print $1}')"
wasm_hash="$(sha256sum build/contracts/eosio.system/eosio.system.wasm | awk '{print $1}')"
test "${abi_hash}" = "${EXPECTED_EOSIO_SYSTEM_ABI_SHA256}"
test "${wasm_hash}" = "${EXPECTED_EOSIO_SYSTEM_WASM_SHA256}"
2 changes: 1 addition & 1 deletion contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ option(SYSTEM_BLOCKCHAIN_PARAMETERS
find_package(cdt)

set(CDT_VERSION_MIN "3.0")
set(CDT_VERSION_SOFT_MAX "4.0")
set(CDT_VERSION_SOFT_MAX "4.1")
# set(CDT_VERSION_HARD_MAX "")

# Check the version of CDT
Expand Down
1 change: 1 addition & 0 deletions contracts/eosio.system/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ add_contract(
${CMAKE_CURRENT_SOURCE_DIR}/src/eosio.system.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/delegate_bandwidth.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/exchange_state.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/finalizer_key.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/name_bidding.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp
Expand Down
129 changes: 126 additions & 3 deletions contracts/eosio.system/include/eosio.system/eosio.system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <eosio/singleton.hpp>
#include <eosio/system.hpp>
#include <eosio/time.hpp>
#include <eosio/instant_finality.hpp>

#include <eosio.system/exchange_state.hpp>
#include <eosio.system/native.hpp>
Expand Down Expand Up @@ -427,6 +428,75 @@ namespace eosiosystem {
EOSLIB_SERIALIZE( producer_info2, (owner)(votepay_share)(last_votepay_share_update) )
};

// finalizer_key_info stores information about a finalizer key.
struct [[eosio::table("finkeys"), eosio::contract("eosio.system")]] finalizer_key_info {
uint64_t id; // automatically generated ID for the key in the table
name finalizer_name; // name of the finalizer owning the key
std::string finalizer_key; // finalizer key in base64url format
std::vector<char> finalizer_key_binary; // finalizer key in binary format in Affine little endian non-montgomery g1

uint64_t primary_key() const { return id; }
uint64_t by_fin_name() const { return finalizer_name.value; }
eosio::checksum256 by_fin_key() const { return eosio::sha256(finalizer_key_binary.data(), finalizer_key_binary.size()); }

bool is_active(uint64_t finalizer_active_key_id) const { return id == finalizer_active_key_id; }
};

typedef eosio::multi_index<
"finkeys"_n, finalizer_key_info,
indexed_by<"byfinname"_n, const_mem_fun<finalizer_key_info, uint64_t, &finalizer_key_info::by_fin_name>>,
indexed_by<"byfinkey"_n, const_mem_fun<finalizer_key_info, eosio::checksum256, &finalizer_key_info::by_fin_key>>
> finalizer_keys_table;

// finalizer_info stores information about a finalizer.
struct [[eosio::table("finalizers"), eosio::contract("eosio.system")]] finalizer_info {
name finalizer_name; // finalizer's name
uint64_t active_key_id; // finalizer's active finalizer key's id in finalizer_keys_table
std::vector<char> active_key_binary; // active finalizer key in binary format
uint32_t finalizer_key_count = 0; // number of finalizer keys registered by this finalizer

uint64_t primary_key() const { return finalizer_name.value; }
};

typedef eosio::multi_index< "finalizers"_n, finalizer_info > finalizers_table;

// finalizer_auth_info stores a finalizer's key id and its finalizer authority.
struct finalizer_auth_info {
finalizer_auth_info() = default;
explicit finalizer_auth_info(const finalizer_info& finalizer);

uint64_t key_id;
eosio::finalizer_authority fin_authority;

bool operator==(const finalizer_auth_info& other) const {
return key_id == other.key_id &&
fin_authority.public_key == other.fin_authority.public_key;
}

EOSLIB_SERIALIZE( finalizer_auth_info, (key_id)(fin_authority) )
};

// A single entry storing information about last proposed finalizers.
struct [[eosio::table("lastpropfins"), eosio::contract("eosio.system")]] last_prop_finalizers_info {
std::vector<finalizer_auth_info> last_proposed_finalizers; // sorted by ascending finalizer key id

uint64_t primary_key() const { return 0; }

EOSLIB_SERIALIZE( last_prop_finalizers_info, (last_proposed_finalizers) )
};

typedef eosio::multi_index< "lastpropfins"_n, last_prop_finalizers_info > last_prop_fins_table;

// A single entry storing next available finalizer key_id so IDs are never reused.
struct [[eosio::table("finkeyidgen"), eosio::contract("eosio.system")]] fin_key_id_generator_info {
uint64_t next_finalizer_key_id = 0;
uint64_t primary_key() const { return 0; }

EOSLIB_SERIALIZE( fin_key_id_generator_info, (next_finalizer_key_id) )
};

typedef eosio::multi_index< "finkeyidgen"_n, fin_key_id_generator_info > fin_key_id_gen_table;

// Voter info. Voter info stores information about the voter:
// - `owner` the voter
// - `proxy` the proxy set by the voter, if any
Expand Down Expand Up @@ -903,6 +973,11 @@ namespace eosiosystem {
voters_table _voters;
producers_table _producers;
producers_table2 _producers2;
finalizer_keys_table _finalizer_keys;
finalizers_table _finalizers;
last_prop_fins_table _last_prop_finalizers;
std::optional<std::vector<finalizer_auth_info>> _last_prop_finalizers_cached;
fin_key_id_gen_table _fin_key_id_generator;
global_state_singleton _global;
global_state2_singleton _global2;
global_state3_singleton _global3;
Expand Down Expand Up @@ -1411,10 +1486,47 @@ namespace eosiosystem {
*
* Deactivate the block producer with account name `producer`.
* @param producer - the block producer account to unregister.
*/
*/
[[eosio::action]]
void unregprod( const name& producer );

/**
* Permanently transition to Savanna consensus by establishing the first finalizer policy.
*
* @pre Requires authority of the system contract.
* @pre The current Telos producer schedule must have active finalizer keys.
*/
[[eosio::action]]
void switchtosvnn();

/**
* Register a BLS finalizer key for a registered producer.
*
* @param finalizer_name - producer account registering the finalizer key.
* @param finalizer_key - public finalizer key in base64url format.
* @param proof_of_possession - proof of possession signature in base64url format.
*/
[[eosio::action]]
void regfinkey( const name& finalizer_name, const std::string& finalizer_key, const std::string& proof_of_possession );

/**
* Activate a registered finalizer key.
*
* @param finalizer_name - producer account activating the finalizer key.
* @param finalizer_key - registered public finalizer key.
*/
[[eosio::action]]
void actfinkey( const name& finalizer_name, const std::string& finalizer_key );

/**
* Delete a registered finalizer key.
*
* @param finalizer_name - producer account deleting the finalizer key.
* @param finalizer_key - registered public finalizer key.
*/
[[eosio::action]]
void delfinkey( const name& finalizer_name, const std::string& finalizer_key );

/**
* Set ram action sets the ram supply.
* @param max_ram_size - the amount of ram supply to set.
Expand Down Expand Up @@ -1789,11 +1901,22 @@ namespace eosiosystem {
void update_votes( const name& voter, const name& proxy, const std::vector<name>& producers, bool voting );
void propagate_weight_change( const voter_info& voter );
double update_producer_votepay_share( const producers_table2::const_iterator& prod_itr,
const time_point& ct,
double shares_rate, bool reset_to_zero = false );
const time_point& ct,
double shares_rate, bool reset_to_zero = false );
double update_total_votepay_share( const time_point& ct,
double additional_shares_delta = 0.0, double shares_rate_delta = 0.0 );

// defined in finalizer_key.cpp
bool is_savanna_consensus();
bool has_active_finalizer_key( const name& producer ) const;
void set_proposed_finalizers( std::vector<finalizer_auth_info> finalizers );
const std::vector<finalizer_auth_info>& get_last_proposed_finalizers();
uint64_t get_next_finalizer_key_id();
finalizers_table::const_iterator get_finalizer_itr( const name& finalizer_name ) const;
std::vector<finalizer_auth_info> get_finalizers_for_producers( const std::vector<producer_location_pair>& producers ) const;
bool active_schedule_matches_last_scheduled_producers( const std::vector<name>& active_schedule ) const;
std::vector<producer_location_pair> get_last_scheduled_producers() const;

template <auto system_contract::*...Ptrs>
class registration {
public:
Expand Down
21 changes: 4 additions & 17 deletions contracts/eosio.system/src/delegate_bandwidth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -263,7 +263,6 @@ namespace eosiosystem {
//create/update/delete refund
auto net_balance = stake_net_delta;
auto cpu_balance = stake_cpu_delta;
bool need_deferred_trx = false;


// net and cpu are same sign by assertions in delegatebw and undelegatebw
Expand Down Expand Up @@ -298,9 +297,6 @@ namespace eosiosystem {

if ( req->is_empty() ) {
refunds_tbl.erase( req );
need_deferred_trx = false;
} else {
need_deferred_trx = true;
}
} else if ( net_balance.amount < 0 || cpu_balance.amount < 0 ) { //need to create refund
refunds_tbl.emplace( from, [&]( refund_request& r ) {
Expand All @@ -319,22 +315,13 @@ namespace eosiosystem {
}
r.request_time = current_time_point();
});
need_deferred_trx = true;
} // else stake increase requested with no existing row in refunds_tbl -> nothing to do with refunds_tbl
} /// end if is_delegating_to_self || is_undelegating

if ( need_deferred_trx ) {
eosio::transaction out;
out.actions.emplace_back( permission_level{from, active_permission},
get_self(), "refund"_n,
from
);
out.delay_sec = refund_delay_sec;
eosio::cancel_deferred( from.value ); // TODO: Remove this line when replacing deferred transactions is fixed
out.send( from.value, from, true );
} else {
eosio::cancel_deferred( from.value );
}
// Deferred transactions are disabled under Spring/Savanna, so the
// refund is no longer scheduled automatically. Any pending refund
// remains in refunds_tbl and must be claimed explicitly with the
// refund action once refund_delay_sec has elapsed.

auto transfer_amount = net_balance + cpu_balance;
if ( 0 < transfer_amount.amount ) {
Expand Down
4 changes: 4 additions & 0 deletions contracts/eosio.system/src/eosio.system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ namespace eosiosystem {
_voters(get_self(), get_self().value),
_producers(get_self(), get_self().value),
_producers2(get_self(), get_self().value),
_finalizer_keys(get_self(), get_self().value),
_finalizers(get_self(), get_self().value),
_last_prop_finalizers(get_self(), get_self().value),
_fin_key_id_generator(get_self(), get_self().value),
_global(get_self(), get_self().value),
_global2(get_self(), get_self().value),
_global3(get_self(), get_self().value),
Expand Down
Loading
Loading