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

Commit

Permalink
refactor native contract for name change #56
Browse files Browse the repository at this point in the history
  • Loading branch information
bytemaster committed Jun 29, 2017
1 parent 557cf4b commit 19b4e82
Show file tree
Hide file tree
Showing 21 changed files with 383 additions and 295 deletions.
6 changes: 3 additions & 3 deletions libraries/chain/chain_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1065,13 +1065,13 @@ uint32_t chain_controller::producer_participation_rate()const
return uint64_t(config::Percent100) * __builtin_popcountll(dpo.recent_slots_filled) / 64;
}

void chain_controller::set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v ) {
void chain_controller::set_validate_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, message_validate_handler v ) {
message_validate_handlers[contract][std::make_pair(scope,action)] = v;
}
void chain_controller::set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v ) {
void chain_controller::set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, precondition_validate_handler v ) {
precondition_validate_handlers[contract][std::make_pair(scope,action)] = v;
}
void chain_controller::set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v ) {
void chain_controller::set_apply_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, apply_handler v ) {
apply_handlers[contract][std::make_pair(scope,action)] = v;
}

Expand Down
8 changes: 4 additions & 4 deletions libraries/chain/include/eos/chain/chain_controller.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,9 +78,9 @@ namespace eos { namespace chain {
* The controller can override any script endpoint with native code.
*/
///@{
void set_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, message_validate_handler v );
void set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, precondition_validate_handler v );
void set_apply_handler( const AccountName& contract, const AccountName& scope, const TypeName& action, apply_handler v );
void set_validate_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, message_validate_handler v );
void set_precondition_validate_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, precondition_validate_handler v );
void set_apply_handler( const AccountName& contract, const AccountName& scope, const ActionName& action, apply_handler v );
//@}

enum validation_steps
Expand Down Expand Up @@ -305,7 +305,7 @@ namespace eos { namespace chain {

node_property_object _node_property_object;

typedef pair<AccountName,TypeName> handler_key;
typedef pair<AccountName,types::Name> handler_key;
map< AccountName, map<handler_key, message_validate_handler> > message_validate_handlers;
map< AccountName, map<handler_key, precondition_validate_handler> > precondition_validate_handlers;
map< AccountName, map<handler_key, apply_handler> > apply_handlers;
Expand Down
9 changes: 5 additions & 4 deletions libraries/chain/include/eos/chain/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,10 @@
: id(0) BOOST_PP_SEQ_FOR_EACH(OBJECT_CTOR2_MACRO, _, FIELDS) \
{ c(*this); }
#define OBJECT_CTOR(...) BOOST_PP_OVERLOAD(OBJECT_CTOR, __VA_ARGS__)(__VA_ARGS__)

#define EOS_SYSTEM_CONTRACT_FUNCTIONS (CreateAccount)(SetCode)
#define EOS_CONTRACT_FUNCTIONS (Transfer)(TransferToLocked)
#define EOS_SYSTEM_CONTRACT_FUNCTIONS (newaccount)(setcode)
#define EOS_CONTRACT_FUNCTIONS (transfer)(lock)
#define EOS_STAKED_BALANCE_CONTRACT_FUNCTIONS \
(CreateProducer)(UpdateProducer)(ApproveProducer)(SetVoteProxy)(AllowVoteProxying)
(setproducer)(okproducer)(setproxy)

namespace eos { namespace chain {
using std::map;
Expand Down Expand Up @@ -112,6 +111,8 @@ namespace eos { namespace chain {
using private_key_type = fc::ecc::private_key;
using chain_id_type = fc::sha256;

using eos::types::Name;
using ActionName = Name;
using eos::types::AccountName;
using eos::types::PermissionName;
using eos::types::Asset;
Expand Down
112 changes: 85 additions & 27 deletions libraries/native_contract/eos_contract.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,89 @@
#include <eos/native_contract/balance_object.hpp>

#include <eos/chain/message_handling_contexts.hpp>
#include <eos/chain/message.hpp>
#include <eos/chain/account_object.hpp>
#include <eos/chain/exceptions.hpp>

namespace native {
namespace eos {
using namespace chain;
using namespace ::eos::chain;
namespace config = ::eos::config;
namespace chain = ::eos::chain;

void CreateAccount_Notify_Eos::validate_preconditions(precondition_validate_context& context) {
auto create = context.msg.as<types::CreateAccount>();
/**
* This method is called when the newaccount message is delivered to @system and @eos is notified.
*
* validate_system_newaccount requires that @eos be notified so we can safely rely on this method
* always being called when a new account is created.
*
* The purpose of this call is to verify the new account has the sufficient funds to populate the
* @staked balance required to reserve the space for the new account.
*/
void precondition_system_newaccount(chain::precondition_validate_context& context ) {
auto create = context.msg.as<types::newaccount>();
const auto& creatorBalance = context.db.get<BalanceObject, byOwnerName>(create.creator);
EOS_ASSERT(creatorBalance.balance >= create.deposit.amount, message_validate_exception,
"Creator '${c}' has insufficient funds to make account creation deposit of ${a}",
("c", create.creator)("a", create.deposit));
}

void ClaimUnlockedEos_Notify_Eos::apply(apply_context& context) {
auto claim = context.msg.as<types::ClaimUnlockedEos>();
const auto& claimant = context.db.get<BalanceObject, byOwnerName>(claim.account);
context.mutable_db.modify(claimant, [&claim](BalanceObject& a) {
a.balance += claim.amount;
/**
* This method is called assuming precondition_system_newaccount succeeds and proceeds to
* deduct the balance of the account creator by deposit, this deposit is supposed to be
* credited to the staked balance the new account in the @staked contract.
*/
void apply_system_newaccount(apply_context& context) {
auto create = context.msg.as<types::newaccount>();

const auto& creatorBalance = context.mutable_db.get<BalanceObject, byOwnerName>(create.creator);
context.mutable_db.modify(creatorBalance, [&create](BalanceObject& b) {
b.balance -= create.deposit.amount;
});
}

void CreateAccount_Notify_Eos::apply(apply_context& context) {
auto create = context.msg.as<types::CreateAccount>();
context.mutable_db.create<BalanceObject>([&create](BalanceObject& b) {
b.ownerName = create.name;
b.balance = create.deposit.amount;
b.balance = 0; //create.deposit.amount; TODO: make sure we credit this in @staked
});
const auto& creatorBalance = context.mutable_db.get<BalanceObject, byOwnerName>(create.creator);
context.mutable_db.modify(creatorBalance, [&create](BalanceObject& b) {
b.balance -= create.deposit.amount;
}

/**
* This method is called when the claim message is delivered to @staked
* staked::validate_staked_claim must require that @eos be notified.
*
* This method trusts that staked::precondition_staked_claim verifies that claim.amount is
* available.
*/
void apply_staked_claim(apply_context& context) {
auto claim = context.msg.as<types::claim>();
const auto& claimant = context.db.get<BalanceObject, byOwnerName>(claim.account);
context.mutable_db.modify(claimant, [&claim](BalanceObject& a) {
a.balance += claim.amount;
});
}

void Transfer::validate(message_validate_context& context) {
auto transfer = context.msg.as<types::Transfer>();
/**
*
* @ingroup native_eos
* @defgroup eos_eos_transfer eos::eos_transfer
*/
///@{
/**
* When transferring EOS the amount must be positive and the receiver must be notified.
*/
void validate_eos_transfer(message_validate_context& context) {
#warning TODO: should transfer validate that the sender is in the provided authorites
auto transfer = context.msg.as<types::transfer>();
try {
EOS_ASSERT(transfer.amount > Asset(0), message_validate_exception, "Must transfer a positive amount");
EOS_ASSERT(context.msg.has_notify(transfer.to), message_validate_exception, "Must notify recipient of transfer");
} FC_CAPTURE_AND_RETHROW((transfer))
}

void Transfer::validate_preconditions(precondition_validate_context& context) {

void precondition_eos_transfer(precondition_validate_context& context) {
const auto& db = context.db;
auto transfer = context.msg.as<types::Transfer>();
auto transfer = context.msg.as<types::transfer>();

try {
db.get<account_object,by_name>(transfer.to); ///< make sure this exists
Expand All @@ -56,9 +94,9 @@ void Transfer::validate_preconditions(precondition_validate_context& context) {
} FC_CAPTURE_AND_RETHROW((transfer))
}

void Transfer::apply(apply_context& context) {
void apply_eos_transfer(apply_context& context) {
auto& db = context.mutable_db;
auto transfer = context.msg.as<types::Transfer>();
auto transfer = context.msg.as<types::transfer>();
const auto& from = db.get<BalanceObject, byOwnerName>(transfer.from);
const auto& to = db.get<BalanceObject, byOwnerName>(transfer.to);
db.modify(from, [&](BalanceObject& a) {
Expand All @@ -68,18 +106,33 @@ void Transfer::apply(apply_context& context) {
a.balance += transfer.amount.amount;
});
}
///@}


void TransferToLocked::validate(message_validate_context& context) {
auto lock = context.msg.as<types::TransferToLocked>();
/**
* When the lock action is delivered to @eos the account should debit the locked amount
* and then require that @staked be notified. @staked will credit the amount to the
* locked balance and adjust votes accordingly.
*
* The locked amount must be possitive.
*
* @defgroup eos_eos_lock eos::eos_lock
*/
///@{
void validate_eos_lock(message_validate_context& context) {
auto lock = context.msg.as<types::lock>();
EOS_ASSERT(lock.amount > 0, message_validate_exception, "Locked amount must be positive");
EOS_ASSERT(lock.to == lock.from || context.msg.has_notify(lock.to),
message_validate_exception, "Recipient account must be notified");
EOS_ASSERT(context.msg.has_notify(config::StakedBalanceContractName), message_validate_exception,
"Staked Balance Contract (${name}) must be notified", ("name", config::StakedBalanceContractName));
}

void TransferToLocked::validate_preconditions(precondition_validate_context& context) {
auto lock = context.msg.as<types::TransferToLocked>();
/**
* The the from account must have sufficient balance
*/
void precondition_eos_lock(precondition_validate_context& context) {
auto lock = context.msg.as<types::lock>();
ShareType balance;
try {
const auto& sender = context.db.get<BalanceObject, byOwnerName>(lock.from);
Expand All @@ -90,12 +143,17 @@ void TransferToLocked::validate_preconditions(precondition_validate_context& con
"Account ${a} lacks sufficient funds to lock ${amt} EOS", ("a", lock.from)("amt", lock.amount));
}

void TransferToLocked::apply(apply_context& context) {
auto lock = context.msg.as<types::TransferToLocked>();
/**
* Deduct the balance from the from account.
*/
void apply_eos_lock(apply_context& context) {
auto lock = context.msg.as<types::lock>();
const auto& locker = context.db.get<BalanceObject, byOwnerName>(lock.from);
context.mutable_db.modify(locker, [&lock](BalanceObject& a) {
a.balance -= lock.amount;
});
}
///@}

} // namespace eos
} // namespace native
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@

#include <chainbase/chainbase.hpp>

namespace native {
namespace eos {
namespace chain = ::eos::chain;
namespace types = ::eos::types;
namespace config = ::eos::config;

/**
* @brief The BalanceObject class tracks the EOS balance for accounts
Expand All @@ -34,6 +38,6 @@ using BalanceMultiIndex = chainbase::shared_multi_index_container<
>
>;

} // namespace eos
} } // namespace native::eos

CHAINBASE_SET_INDEX_TYPE(eos::BalanceObject, eos::BalanceMultiIndex)
CHAINBASE_SET_INDEX_TYPE(native::eos::BalanceObject, native::eos::BalanceMultiIndex)
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,29 @@

#include <eos/types/types.hpp>

namespace eos {
namespace native {
namespace eos { ///< eos native currency contract
namespace chain = ::eos::chain;
namespace types = ::eos::types;

struct CreateAccount_Notify_Eos {
static void validate_preconditions(chain::precondition_validate_context& context);
static void apply(chain::apply_context& context);
};
/// handle apply the newaccount message to the system contract when we are notified
void precondition_system_newaccount(chain::precondition_validate_context& context);
void apply_system_newaccount(chain::apply_context& context);

struct ClaimUnlockedEos_Notify_Eos {
static void validate_preconditions(chain::precondition_validate_context&) {}
static void apply(chain::apply_context& context);
};
/*
void precondition_staked_unlock(chain::precondition_validate_context&) {}
void apply_staked_unlock(chain::apply_context& context);
*/

struct Transfer {
static void validate(chain::message_validate_context& context);
static void validate_preconditions(chain::precondition_validate_context& context);
static void apply(chain::apply_context& context);
};
void validate_eos_transfer(chain::message_validate_context& context);
void precondition_eos_transfer(chain::precondition_validate_context& context);
void apply_eos_transfer(chain::apply_context& context);

struct TransferToLocked {
static void validate(chain::message_validate_context& context);
static void validate_preconditions(chain::precondition_validate_context& context);
static void apply(chain::apply_context& context);
};
void validate_eos_lock(chain::message_validate_context& context);
void precondition_eos_lock(chain::precondition_validate_context& context);
void apply_eos_lock(chain::apply_context& context);

void ClaimUnlockedEos_Notify_Eos(chain::apply_context& context);
void apply_staked_claim(chain::apply_context&);

} // namespace eos
} // namespace native
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,13 @@

#include <boost/multi_index/mem_fun.hpp>

namespace eos {
namespace native {
namespace staked {

using namespace ::eos::chain;
namespace config = ::eos::config;
namespace chain = ::eos::chain;
namespace types = ::eos::types;

FC_DECLARE_EXCEPTION(ProducerRaceOverflowException, 10000000, "Producer Virtual Race time has overflowed");

Expand Down Expand Up @@ -217,8 +223,8 @@ using ProducerScheduleMultiIndex = chainbase::shared_multi_index_container<
>
>;

} // namespace eos
} } // namespace native::staked

CHAINBASE_SET_INDEX_TYPE(eos::ProducerVotesObject, eos::ProducerVotesMultiIndex)
CHAINBASE_SET_INDEX_TYPE(eos::ProxyVoteObject, eos::ProxyVoteMultiIndex)
CHAINBASE_SET_INDEX_TYPE(eos::ProducerScheduleObject, eos::ProducerScheduleMultiIndex)
CHAINBASE_SET_INDEX_TYPE(native::staked::ProducerVotesObject, native::staked::ProducerVotesMultiIndex)
CHAINBASE_SET_INDEX_TYPE(native::staked::ProxyVoteObject, native::staked::ProxyVoteMultiIndex)
CHAINBASE_SET_INDEX_TYPE(native::staked::ProducerScheduleObject, native::staked::ProducerScheduleMultiIndex)
Loading

0 comments on commit 19b4e82

Please sign in to comment.