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

Commit

Permalink
Merge pull request #176 from EOSIO/release/1.5.x
Browse files Browse the repository at this point in the history
Version 1.5.2
  • Loading branch information
arhag authored Jan 16, 2019
2 parents 3a63dae + 79c6659 commit bfd1793
Show file tree
Hide file tree
Showing 9 changed files with 389 additions and 16 deletions.
23 changes: 23 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!-- PLEASE FILL OUT THE FOLLOWING MARKDOWN TEMPLATE -->
<!-- PR title alone should be sufficient to understand changes. -->

## Change Description
<!-- Describe your changes, their justification, AND their impact. Reference issues or pull requests where possible (use '#XX' or 'GH-XX' where XX is the issue or pull request number). -->


## Deployment Changes
- [ ] Deployment Changes
<!-- checked [x] = Deployment changes; unchecked [ ] = no changes, ignore this section -->
<!-- If this PR introduces a change to the contracts that causes deployment to change, please describe the impact. -->


## API Changes
- [ ] API Changes
<!-- checked [x] = API changes; unchecked [ ] = no changes, ignore this section -->
<!-- If this PR introduces API changes, please describe the changes here. What will developers need to know before upgrading to this version? -->


## Documentation Additions
- [ ] Documentation Additions
<!-- checked [x] = Documentation changes; unchecked [ ] = no changes, ignore this section -->
<!-- Describe what must be added to the documentation after merge. -->
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
cmake_minimum_required(VERSION 3.5)
project(eosio_contracts VERSION 1.5.1)
project(eosio_contracts VERSION 1.5.2)

set(EOSIO_CDT_VERSION_MIN "1.4")
set(EOSIO_CDT_VERSION_SOFT_MAX "1.4")
set(EOSIO_CDT_VERSION_SOFT_MAX "1.5")
#set(EOSIO_CDT_VERSION_HARD_MAX "")

find_package(eosio.cdt)
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# eosio.contracts

## Version : 1.5.1
## Version : 1.5.2

The design of the EOSIO blockchain calls for a number of smart contracts that are run at a privileged permission level in order to support functions such as block producer registration and voting, token staking for CPU and network bandwidth, RAM purchasing, multi-sig, etc. These smart contracts are referred to as the system, token, msig and wrap (formerly known as sudo) contracts.

Expand All @@ -14,8 +14,8 @@ The following unprivileged contract(s) are also part of the system.
* [eosio.token](https://github.com/eosio/eosio.contracts/tree/master/eosio.token)

Dependencies:
* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.4)
* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.1)
* [eosio v1.4.x](https://github.com/EOSIO/eos/releases/tag/v1.4.6) to [v1.6.x](https://github.com/EOSIO/eos/releases/tag/v1.6.0)
* [eosio.cdt v1.4.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.4.1) to [v1.5.x](https://github.com/EOSIO/eosio.cdt/releases/tag/v1.5.0)

To build the contracts and the unit tests:
* First, ensure that your __eosio__ is compiled to the core symbol for the EOSIO blockchain that intend to deploy to.
Expand Down
41 changes: 39 additions & 2 deletions eosio.system/include/eosio.system/eosio.system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
#include <eosio.system/exchange_state.hpp>

#include <string>
#include <type_traits>
#include <optional>

namespace eosiosystem {

Expand All @@ -26,6 +28,25 @@ namespace eosiosystem {
using eosio::microseconds;
using eosio::datastream;

template<typename E, typename F>
static inline auto has_field( F flags, E field )
-> std::enable_if_t< std::is_integral_v<F> && std::is_unsigned_v<F> &&
std::is_enum_v<E> && std::is_same_v< F, std::underlying_type_t<E> >, bool>
{
return ( (flags & static_cast<F>(field)) != 0 );
}

template<typename E, typename F>
static inline auto set_field( F flags, E field, bool value = true )
-> std::enable_if_t< std::is_integral_v<F> && std::is_unsigned_v<F> &&
std::is_enum_v<E> && std::is_same_v< F, std::underlying_type_t<E> >, F >
{
if( value )
return ( flags | static_cast<F>(field) );
else
return ( flags & ~static_cast<F>(field) );
}

struct [[eosio::table, eosio::contract("eosio.system")]] name_bid {
name newname;
name high_bidder;
Expand Down Expand Up @@ -151,14 +172,20 @@ namespace eosiosystem {
bool is_proxy = 0; /// whether the voter is a proxy for others


uint32_t reserved1 = 0;
uint32_t flags1 = 0;
uint32_t reserved2 = 0;
eosio::asset reserved3;

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

enum class flags1_fields : uint32_t {
ram_managed = 1,
net_managed = 2,
cpu_managed = 4
};

// explicit serialization macro is not necessary, used here only to improve compilation time
EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(reserved1)(reserved2)(reserved3) )
EOSLIB_SERIALIZE( voter_info, (owner)(proxy)(producers)(staked)(last_vote_weight)(proxied_vote_weight)(is_proxy)(flags1)(reserved2)(reserved3) )
};

typedef eosio::multi_index< "voters"_n, voter_info > voters_table;
Expand Down Expand Up @@ -219,6 +246,16 @@ namespace eosiosystem {

[[eosio::action]]
void setalimits( name account, int64_t ram_bytes, int64_t net_weight, int64_t cpu_weight );

[[eosio::action]]
void setacctram( name account, std::optional<int64_t> ram_bytes );

[[eosio::action]]
void setacctnet( name account, std::optional<int64_t> net_weight );

[[eosio::action]]
void setacctcpu( name account, std::optional<int64_t> cpu_weight );

// functions defined in delegate_bandwidth.cpp

/**
Expand Down
42 changes: 36 additions & 6 deletions eosio.system/src/delegate_bandwidth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,13 @@ namespace eosiosystem {
res.ram_bytes += bytes_out;
});
}
set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount );

auto voter_itr = _voters.find( res_itr->owner.value );
if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) {
int64_t ram_bytes, net, cpu;
get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu );
set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu );
}
}

/**
Expand Down Expand Up @@ -197,7 +203,13 @@ namespace eosiosystem {
userres.modify( res_itr, account, [&]( auto& res ) {
res.ram_bytes -= bytes;
});
set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, res_itr->net_weight.amount, res_itr->cpu_weight.amount );

auto voter_itr = _voters.find( res_itr->owner.value );
if( voter_itr == _voters.end() || !has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed ) ) {
int64_t ram_bytes, net, cpu;
get_resource_limits( res_itr->owner.value, &ram_bytes, &net, &cpu );
set_resource_limits( res_itr->owner.value, res_itr->ram_bytes + ram_gift_bytes, net, cpu );
}

INLINE_ACTION_SENDER(eosio::token, transfer)(
token_account, { {ram_account, active_permission}, {account, active_permission} },
Expand Down Expand Up @@ -280,10 +292,28 @@ namespace eosiosystem {
eosio_assert( 0 <= tot_itr->net_weight.amount, "insufficient staked total net bandwidth" );
eosio_assert( 0 <= tot_itr->cpu_weight.amount, "insufficient staked total cpu bandwidth" );

int64_t ram_bytes, net, cpu;
get_resource_limits( receiver.value, &ram_bytes, &net, &cpu );

set_resource_limits( receiver.value, std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ), tot_itr->net_weight.amount, tot_itr->cpu_weight.amount );
{
bool ram_managed = false;
bool net_managed = false;
bool cpu_managed = false;

auto voter_itr = _voters.find( receiver.value );
if( voter_itr != _voters.end() ) {
ram_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::ram_managed );
net_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::net_managed );
cpu_managed = has_field( voter_itr->flags1, voter_info::flags1_fields::cpu_managed );
}

if( !(net_managed && cpu_managed) ) {
int64_t ram_bytes, net, cpu;
get_resource_limits( receiver.value, &ram_bytes, &net, &cpu );

set_resource_limits( receiver.value,
ram_managed ? ram_bytes : std::max( tot_itr->ram_bytes + ram_gift_bytes, ram_bytes ),
net_managed ? net : tot_itr->net_weight.amount,
cpu_managed ? cpu : tot_itr->cpu_weight.amount );
}
}

if ( tot_itr->net_weight.amount == 0 && tot_itr->cpu_weight.amount == 0 && tot_itr->ram_bytes == 0 ) {
totals_tbl.erase( tot_itr );
Expand Down
146 changes: 145 additions & 1 deletion eosio.system/src/eosio.system.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -120,12 +120,155 @@ namespace eosiosystem {

void system_contract::setalimits( name account, int64_t ram, int64_t net, int64_t cpu ) {
require_auth( _self );

user_resources_table userres( _self, account.value );
auto ritr = userres.find( account.value );
eosio_assert( ritr == userres.end(), "only supports unlimited accounts" );

auto vitr = _voters.find( account.value );
if( vitr != _voters.end() ) {
bool ram_managed = has_field( vitr->flags1, voter_info::flags1_fields::ram_managed );
bool net_managed = has_field( vitr->flags1, voter_info::flags1_fields::net_managed );
bool cpu_managed = has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed );
eosio_assert( !(ram_managed || net_managed || cpu_managed), "cannot use setalimits on an account with managed resources" );
}

set_resource_limits( account.value, ram, net, cpu );
}

void system_contract::setacctram( name account, std::optional<int64_t> ram_bytes ) {
require_auth( _self );

int64_t current_ram, current_net, current_cpu;
get_resource_limits( account.value, &current_ram, &current_net, &current_cpu );

int64_t ram = 0;

if( !ram_bytes ) {
auto vitr = _voters.find( account.value );
eosio_assert( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::ram_managed ),
"RAM of account is already unmanaged" );

user_resources_table userres( _self, account.value );
auto ritr = userres.find( account.value );

ram = ram_gift_bytes;
if( ritr != userres.end() ) {
ram += ritr->ram_bytes;
}

_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, false );
});
} else {
eosio_assert( *ram_bytes >= 0, "not allowed to set RAM limit to unlimited" );

auto vitr = _voters.find( account.value );
if ( vitr != _voters.end() ) {
_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true );
});
} else {
_voters.emplace( account, [&]( auto& v ) {
v.owner = account;
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::ram_managed, true );
});
}

ram = *ram_bytes;
}

set_resource_limits( account.value, ram, current_net, current_cpu );
}

void system_contract::setacctnet( name account, std::optional<int64_t> net_weight ) {
require_auth( _self );

int64_t current_ram, current_net, current_cpu;
get_resource_limits( account.value, &current_ram, &current_net, &current_cpu );

int64_t net = 0;

if( !net_weight ) {
auto vitr = _voters.find( account.value );
eosio_assert( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::net_managed ),
"Network bandwidth of account is already unmanaged" );

user_resources_table userres( _self, account.value );
auto ritr = userres.find( account.value );

if( ritr != userres.end() ) {
net = ritr->net_weight.amount;
}

_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, false );
});
} else {
eosio_assert( *net_weight >= -1, "invalid value for net_weight" );

auto vitr = _voters.find( account.value );
if ( vitr != _voters.end() ) {
_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true );
});
} else {
_voters.emplace( account, [&]( auto& v ) {
v.owner = account;
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::net_managed, true );
});
}

net = *net_weight;
}

set_resource_limits( account.value, current_ram, net, current_cpu );
}

void system_contract::setacctcpu( name account, std::optional<int64_t> cpu_weight ) {
require_auth( _self );

int64_t current_ram, current_net, current_cpu;
get_resource_limits( account.value, &current_ram, &current_net, &current_cpu );

int64_t cpu = 0;

if( !cpu_weight ) {
auto vitr = _voters.find( account.value );
eosio_assert( vitr != _voters.end() && has_field( vitr->flags1, voter_info::flags1_fields::cpu_managed ),
"CPU bandwidth of account is already unmanaged" );

user_resources_table userres( _self, account.value );
auto ritr = userres.find( account.value );

if( ritr != userres.end() ) {
cpu = ritr->cpu_weight.amount;
}

_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, false );
});
} else {
eosio_assert( *cpu_weight >= -1, "invalid value for cpu_weight" );

auto vitr = _voters.find( account.value );
if ( vitr != _voters.end() ) {
_voters.modify( vitr, same_payer, [&]( auto& v ) {
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true );
});
} else {
_voters.emplace( account, [&]( auto& v ) {
v.owner = account;
v.flags1 = set_field( v.flags1, voter_info::flags1_fields::cpu_managed, true );
});
}

cpu = *cpu_weight;
}

set_resource_limits( account.value, current_ram, current_net, cpu );
}

void system_contract::rmvproducer( name producer ) {
require_auth( _self );
auto prod = _producers.find( producer.value );
Expand Down Expand Up @@ -308,7 +451,8 @@ EOSIO_DISPATCH( eosiosystem::system_contract,
// native.hpp (newaccount definition is actually in eosio.system.cpp)
(newaccount)(updateauth)(deleteauth)(linkauth)(unlinkauth)(canceldelay)(onerror)(setabi)
// eosio.system.cpp
(init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(rmvproducer)(updtrevision)(bidname)(bidrefund)
(init)(setram)(setramrate)(setparams)(setpriv)(setalimits)(setacctram)(setacctnet)(setacctcpu)
(rmvproducer)(updtrevision)(bidname)(bidrefund)
// delegate_bandwidth.cpp
(buyrambytes)(buyram)(sellram)(delegatebw)(undelegatebw)(refund)
// voting.cpp
Expand Down
1 change: 0 additions & 1 deletion eosio.system/src/voting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@ namespace eosiosystem {
if ( proxy ) {
eosio_assert( producers.size() == 0, "cannot vote for producers and proxy at same time" );
eosio_assert( voter_name != proxy, "cannot proxy to self" );
require_recipient( proxy );
} else {
eosio_assert( producers.size() <= 30, "attempt to vote for too many producers" );
for( size_t i = 1; i < producers.size(); ++i ) {
Expand Down
2 changes: 1 addition & 1 deletion tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
cmake_minimum_required( VERSION 3.5 )

set(EOSIO_VERSION_MIN "1.4")
set(EOSIO_VERSION_SOFT_MAX "1.4")
set(EOSIO_VERSION_SOFT_MAX "1.6")
#set(EOSIO_VERSION_HARD_MAX "")

find_package(eosio)
Expand Down
Loading

0 comments on commit bfd1793

Please sign in to comment.