Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIP-40 establish permissions, integrate register_address_on_domain. #297

Merged
merged 16 commits into from
May 4, 2023
Merged
1 change: 1 addition & 0 deletions contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ add_subdirectory(fio.request.obt)
add_subdirectory(fio.tpid)
add_subdirectory(fio.treasury)
add_subdirectory(fio.escrow)
add_subdirectory(fio.perms)
add_subdirectory(fio.staking)
2 changes: 2 additions & 0 deletions contracts/eosio.msig/src/eosio.msig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ namespace eosio {
_proposer == fioio::TREASURYACCOUNT ||
_proposer == fioio::FIOSYSTEMACCOUNT ||
_proposer == fioio::FIOACCOUNT ||
//FIP-40
_proposer == fioio::PERMSACCOUNT ||
isTopProd)
) {
//collect fees.
Expand Down
88 changes: 79 additions & 9 deletions contracts/fio.address/fio.address.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
* @license FIO Foundation ( https://github.com/fioprotocol/fio/blob/master/LICENSE ) Dapix
*/

/*
* FIP-40
todo fio.address burnexpired /burn_expired Burn all the associated domain permissions when FIO Domain is burned.
todo fio.address xferdomain /transfer_fio_domain Burn all the associated domain permissions when FIO Domain is transferred.
*/

#include "fio.address.hpp"
#include <fio.fee/fio.fee.hpp>
#include <fio.common/fio.common.hpp>
Expand All @@ -13,6 +19,7 @@
#include <eosiolib/asset.hpp>
#include <fio.request.obt/fio.request.obt.hpp> //TEMP FOR XFERADDRESS
#include <fio.escrow/fio.escrow.hpp>
#include <fio.perms/fio.perms.hpp>

namespace fioio {

Expand All @@ -33,6 +40,8 @@ namespace fioio {
eosiosystem::producers_table producers;
eosiosystem::locked_tokens_table lockedTokensTable;
nfts_table nftstable;
permissions_table permissions_table;
access_table accesses_table;
config appConfig;

//FIP-39 begin
Expand All @@ -56,8 +65,9 @@ namespace fioio {
voters(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
topprods(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
producers(SYSTEMACCOUNT, SYSTEMACCOUNT.value),
lockedTokensTable(SYSTEMACCOUNT,
SYSTEMACCOUNT.value),
lockedTokensTable(SYSTEMACCOUNT,SYSTEMACCOUNT.value),
permissions_table(PERMSACCOUNT,PERMSACCOUNT.value),
accesses_table(PERMSACCOUNT,PERMSACCOUNT.value),
//FIP-39 begin
fionameinfo(_self, _self.value){
//FIP-39 end
Expand Down Expand Up @@ -282,7 +292,25 @@ namespace fioio {
const bool isPublic = domains_iter->is_public;
uint64_t domain_owner = domains_iter->account;

if (!isPublic) {
//object_type, object_name, and permission_name get hashed for permission control hash
bool hasDomainAccess = false;
string permctrl = REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE+fa.fiodomain+REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;
uint128_t permctrlhash = string_to_uint128_hash(permctrl.c_str());
auto permissionbyctrl = permissions_table.get_index<"bypermctrl"_n>();
auto permsbypermctrl_iter = permissionbyctrl.find(permctrlhash);


if(permsbypermctrl_iter != permissionbyctrl.end()){
string accessctrl = actor.to_string()+to_string(permsbypermctrl_iter->id);
uint128_t accessctrlhash = string_to_uint128_hash(accessctrl.c_str());
auto accessesbyctrl = accesses_table.get_index<"byaccess"_n>();
auto accessesbyctrl_iter = accessesbyctrl.find(accessctrlhash);
if(accessesbyctrl_iter != accessesbyctrl.end()){
hasDomainAccess = true;
}
}

if (!(isPublic || hasDomainAccess)) {
fio_400_assert(domain_owner == actor.value, "fio_address", fa.fioaddress,
"FIO Domain is not public. Only owner can create FIO Addresses.",
ErrorInvalidFioNameFormat);
Expand Down Expand Up @@ -1352,10 +1380,37 @@ namespace fioio {
while (domainiter != domains.end()) {
const uint64_t expire = domainiter->expiration;
if ((expire + DOMAINWAITFORBURNDAYS) < nowtime) {

//clear the domain permissions.
//if there are domain permissions.
//call to clear them and return.
//if no permissions continue the process.
string permcontrol = REGISTER_ADDRESS_ON_DOMAIN_OBJECT_TYPE + domainiter->name + REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME;

const uint128_t permcontrolHash = string_to_uint128_hash(permcontrol.c_str());

auto permissionsbycontrolhash = permissions_table.get_index<"bypermctrl"_n>();
auto permctrl_iter = permissionsbycontrolhash.find(permcontrolHash);
if (permctrl_iter != permissionsbycontrolhash.end() ) {
//delete the permission, and the granted accounts,
// clear all the permissions for this domain.
//FIP-40
action(
permission_level{get_self(), "active"_n},
"fio.perms"_n,
"clearperm"_n,
std::make_tuple(REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME, domainiter->name)
).send();

// increment the number record processed by one
//this increment helps manage the time used by the burn
recordProcessed++;
if (recordProcessed == numbertoburn) { break; }
}

const auto domainhash = domainiter->domainhash;
auto nameexpidx = fionames.get_index<"bydomain"_n>();
auto nameiter = nameexpidx.find(domainhash);

while (nameiter != nameexpidx.end()) {
auto nextname = nameiter;
nextname++;
Expand Down Expand Up @@ -2015,11 +2070,14 @@ namespace fioio {

auto burnqbyname = nftburnqueue.get_index<"byaddress"_n>();
auto nftburnq_iter = burnqbyname.begin();
auto contractsbyname = nftstable.get_index<"byaddress"_n>();
auto contractsbyname = nftstable.get_index<"byaddress"_n>(); //more than 3k records ed@edge
uint16_t counter = 0;
auto nft_iter = contractsbyname.begin();
while (nftburnq_iter != burnqbyname.end()) {
nft_iter = contractsbyname.find(nftburnq_iter->fio_address_hash);
//as soon as this has toooo many records it will not execute in a tx, we limit the number
// of accounts granted a permission see fio.perms.hpp MAX_GRANTEES in
// the code for a more detailed explanation
nft_iter = contractsbyname.find(nftburnq_iter->fio_address_hash); //search delay.
counter++;
if (nft_iter != contractsbyname.end()) { // if row, delete an nft
nft_iter = contractsbyname.erase(nft_iter);
Expand Down Expand Up @@ -2404,6 +2462,17 @@ namespace fioio {
domainsbyname.modify(domains_iter, actor, [&](struct domain &a) {
a.account = nm.value;
});

//clear all the permissions for this domainas paert of the transfer
//note we limit grantees to 100 in the protocol to permit this kind of operation.
//see fio.perms.hpp MAX_GRANTEES documentaiton for further details.
//FIP-40
action(
permission_level{get_self(), "active"_n},
"fio.perms"_n,
"clearperm"_n,
std::make_tuple(REGISTER_ADDRESS_ON_DOMAIN_PERMISSION_NAME, fio_domain)
).send();

//fees
const uint64_t fee_amount = fee_iter->suf_amount;
Expand Down Expand Up @@ -2514,9 +2583,10 @@ namespace fioio {
void decrcounter(const string &fio_address, const int32_t &step) {

check(step > 0, "step must be greater than 0");
//FIP-40
check((has_auth(AddressContract) || has_auth(TokenContract) || has_auth(TREASURYACCOUNT) || has_auth(STAKINGACCOUNT) ||
has_auth(REQOBTACCOUNT) || has_auth(SYSTEMACCOUNT) || has_auth(FeeContract)),
"missing required authority of fio.address, fio.token, fio.fee, fio.treasury, fio.reqobt, fio.system, fio.staking ");
has_auth(REQOBTACCOUNT) || has_auth(SYSTEMACCOUNT) || has_auth(FeeContract) || has_auth(PERMSACCOUNT)),
"missing required authority of fio.address, fio.token, fio.fee, fio.treasury, fio.reqobt, fio.system, fio.staking fio.perms");

auto namesbyname = fionames.get_index<"byname"_n>();
auto fioname_iter = namesbyname.find(string_to_uint128_hash(fio_address.c_str()));
Expand Down Expand Up @@ -2578,7 +2648,7 @@ namespace fioio {

};

EOSIO_DISPATCH(FioNameLookup, (regaddress)(addaddress)(remaddress)(remalladdr)(regdomain)(renewdomain)(renewaddress)
EOSIO_DISPATCH(FioNameLookup,(regaddress)(addaddress)(remaddress)(remalladdr)(regdomain)(renewdomain)(renewaddress)
(setdomainpub)(burnexpired)(decrcounter)(bind2eosio)(burnaddress)(xferdomain)(xferaddress)(addbundles)(xferescrow)
(addnft)(remnft)(remallnfts)(burnnfts)(regdomadd)(updcryptkey))
}
2 changes: 2 additions & 0 deletions contracts/fio.common/fio.accounts.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ namespace fioio {
static const name EscrowContract = name("fio.escrow");
static const name FIOACCOUNT = name("fio");
static const name FIOORACLEContract = name("fio.oracle");
//FIP-40
static const name PERMSACCOUNT = name("fio.perms");

static constexpr name FIOISSUER = name("eosio"_n);
static constexpr eosio::symbol FIOSYMBOL = eosio::symbol("FIO", 9);
Expand Down
11 changes: 10 additions & 1 deletion contracts/fio.common/fio.common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@
#define ADD_NFT_ENDPOINT "add_nft"
#define REM_NFT_ENDPOINT "remove_nft"
#define REM_ALL_NFTS_ENDPOINT "remove_all_nfts"
//FIP-40
#define ADD_PERMISSION_ENDPOINT "add_fio_permission"
#define REMOVE_PERMISSION_ENDPOINT "remove_fio_permission"
#define PERMISSION_OBJECT_TYPE_DOMAIN "domain"
//FIP-38 begin
#define NEW_FIO_CHAIN_ACCOUNT_ENDPOINT "new_fio_chain_account"
//FIP-38 end
Expand Down Expand Up @@ -145,7 +149,9 @@ namespace fioio {
actor == fioio::FIOSYSTEMACCOUNT ||
actor == fioio::FIOACCOUNT ||
actor == fioio::EscrowContract ||
actor == FIOORACLEContract);
actor == FIOORACLEContract ||
//FIP-40
actor == PERMSACCOUNT);
}

static constexpr uint64_t string_to_uint64_hash(const char *str) {
Expand Down Expand Up @@ -514,6 +520,9 @@ namespace fioio {
static const uint64_t BUNDLEVOTERAM = 0; //integrated.
static const uint64_t ADDNFTRAMBASE = 512;
static const uint64_t ADDNFTRAM = 2048;
//FIP-40
static const uint64_t ADDPERMISSIONRAMBASE = 2560;
static const uint64_t ADDPERMISSIONRAM = 2048;
static const uint64_t LISTDOMAINRAM = 1536; // FIOESCROW - List Domain 1140 bytes round to 512 x 3
//FIP-38 begin
static const uint64_t NEWFIOCHAINACCOUNTRAM = 0;
Expand Down
6 changes: 6 additions & 0 deletions contracts/fio.common/fioerror.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,12 @@ namespace fioio {
constexpr auto ErrorRetireQuantity = ident | httpDataError | 159;
constexpr auto ErrorInvalidMemo = ident | httpDataError | 160;
constexpr auto ErrorDomainSaleNotFound = ident | httpInvalidError | 161; // domain not found in domainsales table
//FIP-40
constexpr auto ErrorInvalidPermissionName = ident | httpDataError | 162;
constexpr auto ErrorInvalidPermissionInfo = ident | httpDataError | 163;
constexpr auto ErrorInvalidObjectName = ident | httpDataError | 164;
constexpr auto ErrorInvalidGranteeAccount = ident | httpDataError | 165;
constexpr auto ErrorPermissionExists = ident | httpDataError | 166;

/**
* Helper funtions for detecting rich error messages and extracting bitfielded values
Expand Down
14 changes: 14 additions & 0 deletions contracts/fio.perms/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_contract(fio.perms fio.perms ${CMAKE_CURRENT_SOURCE_DIR}/fio.perms.cpp)

target_include_directories(fio.perms
PUBLIC
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/../fio.perms/include
${CMAKE_CURRENT_SOURCE_DIR}/../fio.address/include
${CMAKE_CURRENT_SOURCE_DIR}/../
)


set_target_properties(fio.perms
PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}")
Loading