Remove file write operation
This commit is contained in:
parent
f777aae08e
commit
17693e6299
7 changed files with 8 additions and 230 deletions
|
|
@ -23,7 +23,6 @@
|
|||
#include <graphene/chain/block_summary_object.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/delegate_object.hpp>
|
||||
#include <graphene/chain/file_object.hpp>
|
||||
#include <graphene/chain/global_property_object.hpp>
|
||||
#include <graphene/chain/key_object.hpp>
|
||||
#include <graphene/chain/limit_order_object.hpp>
|
||||
|
|
@ -121,7 +120,6 @@ void database::initialize_indexes()
|
|||
add_index< primary_index<withdraw_permission_index > >();
|
||||
add_index< primary_index<bond_index > >();
|
||||
add_index< primary_index<bond_offer_index > >();
|
||||
add_index< primary_index<file_object_index> >();
|
||||
add_index< primary_index<simple_index<vesting_balance_object> > >();
|
||||
add_index< primary_index<worker_index> >();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,117 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015, Cryptonomex, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is provided for evaluation in private test networks only, until September 8, 2015. After this date, this license expires and
|
||||
* the code may not be used, modified or distributed for any purpose. Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted until September 8, 2015, provided that the following conditions are met:
|
||||
*
|
||||
* 1. The code and/or derivative works are used only for private test networks consisting of no more than 10 P2P nodes.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
namespace graphene { namespace chain {
|
||||
|
||||
|
||||
/**
|
||||
* @brief provides for persistant storage of arbitrary data
|
||||
*
|
||||
* Smart contracts need data to be stored persistantly that can be shared with
|
||||
* other smart contracts. There is a cost associated with storing data, especially if
|
||||
* that data will be kept in RAM.
|
||||
*
|
||||
* File objects allow smart contracts to interact with persistant storage much like
|
||||
* traditional programs interact with files on disk. The cost of accessing a file
|
||||
* object to modify it is much higher than the cost to simply read it because the
|
||||
* the database must make a backup of the file for the undo history in the event
|
||||
* of a blockchain reorganization or failure in evaluation. For this reason files
|
||||
* are limited to 2^16 bytes and smart contracts will have to use multiple files if
|
||||
* they need to store additional data.
|
||||
*
|
||||
* Every file has an automatic expiration date at which point in time it will be
|
||||
* deleted unless a fee is paid to extend its life time.
|
||||
*
|
||||
* The contents of all files are public, but not to scripts. A smart contract attempting
|
||||
* to access the contents of a file must have permission to read the file. The purpose
|
||||
* of this restriction is to help users monetize the trust associated with publishing
|
||||
* data. Anyone could re-publish the data under a new file, but the trust in the
|
||||
* quality of the data would not be the same as the original file.
|
||||
*/
|
||||
class file_object : public graphene::db::annotated_object<file_object>
|
||||
{
|
||||
public:
|
||||
static const uint8_t space_id = protocol_ids;
|
||||
static const uint8_t type_id = file_object_type;
|
||||
|
||||
/**
|
||||
* @brief sets bits that control the permissions granted to smart contracts regarding this data.
|
||||
*/
|
||||
enum permision_flags
|
||||
{
|
||||
owner_read = 0x01,
|
||||
owner_write = 0x02,
|
||||
group_read = 0x04,
|
||||
group_write = 0x08,
|
||||
all_read = 0x10,
|
||||
execute = 0x20 ///< set if data contains virtual machine instructions
|
||||
};
|
||||
|
||||
/**
|
||||
* The owner can access this file based upon the @ref permissions flags
|
||||
*
|
||||
* @note - if the owner removes write permission from himself then the file
|
||||
* will be imutable thereafter.
|
||||
*/
|
||||
account_id_type owner;
|
||||
/** any account that has been white listed by this group can read/write
|
||||
* @ref data based upon the @ref permissions flags.
|
||||
*/
|
||||
account_id_type group;
|
||||
/**
|
||||
* Bits set according to @ref permission_flags
|
||||
*/
|
||||
uint8_t permissions = owner_read | owner_write | all_read;
|
||||
|
||||
/**
|
||||
* Files consume memory and thus are cleaned up unless a fee is paid to
|
||||
* keep them alive.
|
||||
*/
|
||||
time_point_sec expiration;
|
||||
|
||||
/**
|
||||
* The maximum data size for a file is 2^16 bytes so that the
|
||||
* undo history doesn't have to backup larger files. If a smart contract
|
||||
* requires more data then it can create more file objects.
|
||||
*/
|
||||
vector<char> data;
|
||||
};
|
||||
|
||||
struct by_expiration;
|
||||
struct by_owner;
|
||||
struct by_group;
|
||||
/**
|
||||
* @ingroup object_index
|
||||
*/
|
||||
typedef multi_index_container<
|
||||
file_object,
|
||||
indexed_by<
|
||||
hashed_unique< tag<by_id>, member< object, object_id_type, &object::id > >,
|
||||
hashed_non_unique< tag<by_owner>, member< file_object, account_id_type, &file_object::owner > >,
|
||||
hashed_non_unique< tag<by_group>, member< file_object, account_id_type, &file_object::group > >,
|
||||
ordered_non_unique< tag<by_expiration>, member<file_object, time_point_sec, &file_object::expiration> >
|
||||
>
|
||||
> file_object_multi_index_type;
|
||||
|
||||
typedef generic_index<file_object, file_object_multi_index_type> file_object_index;
|
||||
|
||||
} }
|
||||
|
||||
FC_REFLECT_ENUM( graphene::chain::file_object::permision_flags, (owner_read)(owner_write)(group_read)(group_write)(all_read)(execute) )
|
||||
FC_REFLECT_DERIVED( graphene::chain::file_object, (graphene::db::object), (owner)(group)(permissions)(expiration)(data) )
|
||||
|
|
@ -1248,81 +1248,6 @@ namespace graphene { namespace chain {
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief create/update the contents of a file.
|
||||
*
|
||||
* Any account may pay a fee and write no data to extend the lease seconds
|
||||
* on a file.
|
||||
*
|
||||
* If the file size increasees, the current lease_seconds will be adjusted downward to maintain
|
||||
* the same byte-days-leased. Then any new leased seconds will be added based upon the
|
||||
* new file size.
|
||||
*
|
||||
* @see file_object
|
||||
*/
|
||||
struct file_write_operation
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* The fee charges is proportional to @ref file_size * @ref lease_seconds
|
||||
*/
|
||||
asset fee;
|
||||
/**
|
||||
* THe account that is paying the update fee
|
||||
*/
|
||||
account_id_type payer;
|
||||
|
||||
/** file_id 0 indicates a new file should be created */
|
||||
file_id_type file_id;
|
||||
|
||||
/** may read/write accoding to flags, write permission is required to change owner/group/flags */
|
||||
account_id_type owner;
|
||||
|
||||
/** may read/write according fo flags, but may not update flags or owner */
|
||||
account_id_type group;
|
||||
|
||||
/**
|
||||
* Must be less than or equal to 0x2f
|
||||
*/
|
||||
uint8_t flags = 0;
|
||||
|
||||
/**
|
||||
* If the file doesn't exist, it will be intialized to file_size with 0
|
||||
* before writing data.
|
||||
*
|
||||
* @pre data.size() + offset <= 2^16
|
||||
*/
|
||||
uint16_t offset = 0;
|
||||
vector<char> data;
|
||||
|
||||
/**
|
||||
* The length of time to extend the lease on the file, must be less
|
||||
* than 10 years.
|
||||
*/
|
||||
uint32_t lease_seconds = 0;
|
||||
|
||||
/**
|
||||
* File size must be greater than 0
|
||||
*/
|
||||
uint16_t file_size = 0;
|
||||
|
||||
/**
|
||||
* If file_id is not 0, then precondition checksum verifies that
|
||||
* the file contents are as expected prior to writing data.
|
||||
*/
|
||||
optional<checksum_type> precondition_checksum;
|
||||
|
||||
account_id_type fee_payer()const { return payer; }
|
||||
void get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const { active_auth_set.insert(fee_payer()); }
|
||||
void validate()const;
|
||||
share_type calculate_fee( const fee_schedule_type& k )const;
|
||||
|
||||
void get_balance_delta( balance_accumulator& acc, const operation_result& result = asset())const
|
||||
{
|
||||
acc.adjust( fee_payer(), -fee );
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup operations
|
||||
*
|
||||
|
|
@ -1617,7 +1542,6 @@ namespace graphene { namespace chain {
|
|||
withdraw_permission_delete_operation,
|
||||
fill_order_operation,
|
||||
global_parameters_update_operation,
|
||||
file_write_operation,
|
||||
vesting_balance_create_operation,
|
||||
vesting_balance_withdraw_operation,
|
||||
bond_create_offer_operation,
|
||||
|
|
@ -1852,8 +1776,6 @@ FC_REFLECT( graphene::chain::withdraw_permission_claim_operation, (fee)(withdraw
|
|||
FC_REFLECT( graphene::chain::withdraw_permission_delete_operation, (fee)(withdraw_from_account)(authorized_account)
|
||||
(withdrawal_permission) )
|
||||
|
||||
FC_REFLECT( graphene::chain::file_write_operation, (fee)(payer)(file_id)(owner)(group)(flags)(offset)(data)(lease_seconds)(file_size)(precondition_checksum) )
|
||||
|
||||
FC_REFLECT( graphene::chain::bond_create_offer_operation, (fee)(creator)(offer_to_borrow)(amount)(min_match)(collateral_rate)(min_loan_period_sec)(loan_period_sec)(interest_apr) )
|
||||
FC_REFLECT( graphene::chain::bond_cancel_offer_operation, (fee)(creator)(offer_id)(refund) )
|
||||
FC_REFLECT( graphene::chain::bond_accept_offer_operation, (fee)(claimer)(lender)(borrower)(offer_id)(amount_borrowed)(amount_collateral) )
|
||||
|
|
|
|||
|
|
@ -116,7 +116,6 @@ namespace graphene { namespace chain {
|
|||
withdraw_permission_object_type,
|
||||
bond_offer_object_type,
|
||||
bond_object_type,
|
||||
file_object_type,
|
||||
vesting_balance_object_type,
|
||||
worker_object_type,
|
||||
OBJECT_TYPE_COUNT ///< Sentry value which contains the number of different object types
|
||||
|
|
@ -163,7 +162,6 @@ namespace graphene { namespace chain {
|
|||
class withdraw_permission_object;
|
||||
class bond_object;
|
||||
class bond_offer_object;
|
||||
class file_object;
|
||||
class vesting_balance_object;
|
||||
class witness_schedule_object;
|
||||
class worker_object;
|
||||
|
|
@ -183,7 +181,6 @@ namespace graphene { namespace chain {
|
|||
typedef object_id< protocol_ids, withdraw_permission_object_type,withdraw_permission_object> withdraw_permission_id_type;
|
||||
typedef object_id< protocol_ids, bond_offer_object_type, bond_offer_object> bond_offer_id_type;
|
||||
typedef object_id< protocol_ids, bond_object_type, bond_object> bond_id_type;
|
||||
typedef object_id< protocol_ids, file_object_type, file_object> file_id_type;
|
||||
typedef object_id< protocol_ids, vesting_balance_object_type, vesting_balance_object> vesting_balance_id_type;
|
||||
typedef object_id< protocol_ids, worker_object_type, worker_object> worker_id_type;
|
||||
|
||||
|
|
@ -386,7 +383,6 @@ namespace graphene { namespace chain {
|
|||
uint32_t cancel_bond_offer_fee;
|
||||
uint32_t accept_bond_offer_fee;
|
||||
uint32_t claim_bond_collateral_fee;
|
||||
uint32_t file_storage_fee_per_day; ///< the cost of leasing a file with 2^16 bytes for 1 day
|
||||
uint32_t vesting_balance_create_fee;
|
||||
uint32_t vesting_balance_withdraw_fee;
|
||||
uint32_t global_settle_fee;
|
||||
|
|
@ -509,7 +505,6 @@ FC_REFLECT_ENUM( graphene::chain::object_type,
|
|||
(withdraw_permission_object_type)
|
||||
(bond_offer_object_type)
|
||||
(bond_object_type)
|
||||
(file_object_type)
|
||||
(vesting_balance_object_type)
|
||||
(worker_object_type)
|
||||
(OBJECT_TYPE_COUNT)
|
||||
|
|
@ -568,7 +563,6 @@ FC_REFLECT( graphene::chain::fee_schedule_type,
|
|||
(cancel_bond_offer_fee)
|
||||
(accept_bond_offer_fee)
|
||||
(claim_bond_collateral_fee)
|
||||
(file_storage_fee_per_day)
|
||||
(vesting_balance_create_fee)
|
||||
(vesting_balance_withdraw_fee)
|
||||
(global_settle_fee)
|
||||
|
|
@ -617,7 +611,6 @@ FC_REFLECT_TYPENAME( graphene::chain::operation_history_id_type )
|
|||
FC_REFLECT_TYPENAME( graphene::chain::withdraw_permission_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bond_offer_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::bond_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::file_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::vesting_balance_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::worker_id_type )
|
||||
FC_REFLECT_TYPENAME( graphene::chain::relative_key_id_type )
|
||||
|
|
|
|||
|
|
@ -717,20 +717,6 @@ void asset_update_feed_producers_operation::validate() const
|
|||
{
|
||||
FC_ASSERT( fee.amount >= 0 );
|
||||
}
|
||||
void file_write_operation::validate()const
|
||||
{
|
||||
FC_ASSERT( uint32_t(offset) + data.size() <= file_size );
|
||||
FC_ASSERT( flags <= 0x2f );
|
||||
FC_ASSERT( file_size > 0 );
|
||||
/** less than 10 years to prevent overflow of 64 bit numbers in the value*lease_seconds*file_size calculation */
|
||||
FC_ASSERT( lease_seconds < 60*60*24*365*10 );
|
||||
}
|
||||
|
||||
share_type file_write_operation::calculate_fee( const fee_schedule_type& k )const
|
||||
{
|
||||
return ((((k.file_storage_fee_per_day * lease_seconds)/(60*60*24))*file_size)/0xff) + ((data.size() * k.data_fee)/1024);
|
||||
}
|
||||
|
||||
|
||||
void vesting_balance_create_operation::get_required_auth(flat_set<account_id_type>& active_auth_set, flat_set<account_id_type>&)const
|
||||
{
|
||||
|
|
|
|||
|
|
@ -173,9 +173,6 @@ struct operation_get_impacted_accounts
|
|||
}
|
||||
|
||||
void operator()( const asset_create_operation& o )const { }
|
||||
void operator()( const file_write_operation& o )const {
|
||||
_impacted.insert( o.owner );
|
||||
}
|
||||
|
||||
void operator()( const asset_update_operation& o )const {
|
||||
if( o.new_issuer )
|
||||
|
|
|
|||
|
|
@ -18,7 +18,6 @@
|
|||
#include <graphene/chain/operations.hpp>
|
||||
#include <graphene/chain/bond_object.hpp>
|
||||
#include <graphene/chain/vesting_balance_object.hpp>
|
||||
#include <graphene/chain/file_object.hpp>
|
||||
#include <graphene/chain/withdraw_permission_object.hpp>
|
||||
#include <graphene/chain/proposal_object.hpp>
|
||||
#include <graphene/chain/witness_object.hpp>
|
||||
|
|
@ -69,7 +68,7 @@ string remove_namespace( string str )
|
|||
|
||||
template<typename T>
|
||||
void generate_serializer();
|
||||
template<typename T>
|
||||
template<typename T>
|
||||
void register_serializer();
|
||||
|
||||
|
||||
|
|
@ -96,7 +95,7 @@ struct js_name<fc::array<T,N>>
|
|||
};
|
||||
template<size_t N> struct js_name<fc::array<char,N>> { static std::string name(){ return "bytes "+ fc::to_string(N); }; };
|
||||
template<size_t N> struct js_name<fc::array<uint8_t,N>> { static std::string name(){ return "bytes "+ fc::to_string(N); }; };
|
||||
template<typename T> struct js_name< fc::optional<T> > { static std::string name(){ return "optional " + js_name<T>::name(); } };
|
||||
template<typename T> struct js_name< fc::optional<T> > { static std::string name(){ return "optional " + js_name<T>::name(); } };
|
||||
template<> struct js_name< object_id_type > { static std::string name(){ return "object_id_type"; } };
|
||||
template<typename T> struct js_name< fc::flat_set<T> > { static std::string name(){ return "set " + js_name<T>::name(); } };
|
||||
template<typename T> struct js_name< std::vector<T> > { static std::string name(){ return "array " + js_name<T>::name(); } };
|
||||
|
|
@ -115,8 +114,8 @@ template<> struct js_name< time_point_sec > { static std::string name(){ retu
|
|||
template<uint8_t S, uint8_t T, typename O>
|
||||
struct js_name<graphene::db::object_id<S,T,O> >
|
||||
{
|
||||
static std::string name(){
|
||||
return "protocol_id_type \"" + remove_namespace(fc::get_typename<O>::name()) + "\"";
|
||||
static std::string name(){
|
||||
return "protocol_id_type \"" + remove_namespace(fc::get_typename<O>::name()) + "\"";
|
||||
};
|
||||
};
|
||||
|
||||
|
|
@ -132,7 +131,7 @@ struct js_name< fc::flat_map<K,V> > { static std::string name(){ return "map ("
|
|||
|
||||
template<typename... T> struct js_sv_name;
|
||||
|
||||
template<typename A> struct js_sv_name<A>
|
||||
template<typename A> struct js_sv_name<A>
|
||||
{ static std::string name(){ return "\n " + js_name<A>::name(); } };
|
||||
|
||||
template<typename A, typename... T>
|
||||
|
|
@ -142,10 +141,10 @@ struct js_sv_name<A,T...> { static std::string name(){ return "\n " + js_nam
|
|||
template<typename... T>
|
||||
struct js_name< fc::static_variant<T...> >
|
||||
{
|
||||
static std::string name( std::string n = ""){
|
||||
static std::string name( std::string n = ""){
|
||||
static const std::string name = n;
|
||||
if( name == "" )
|
||||
return "static_variant [" + js_sv_name<T...>::name() + "\n]";
|
||||
return "static_variant [" + js_sv_name<T...>::name() + "\n]";
|
||||
else return name;
|
||||
}
|
||||
};
|
||||
|
|
@ -290,7 +289,7 @@ class register_member_visitor
|
|||
}
|
||||
};
|
||||
|
||||
template<typename T, bool reflected>
|
||||
template<typename T, bool reflected>
|
||||
struct serializer
|
||||
{
|
||||
static_assert( fc::reflector<T>::is_defined::value == reflected, "invalid template arguments" );
|
||||
|
|
|
|||
Loading…
Reference in a new issue