Skip to content
This repository has been archived by the owner on Feb 21, 2019. It is now read-only.

Commit

Permalink
Update asset properties and control
Browse files Browse the repository at this point in the history
Added flags for freezing markets, balances, and unlimited supply for
User Issued Assets
Added ability to change the issuer.
  • Loading branch information
bytemaster committed Dec 3, 2014
1 parent 3475bcc commit fcbb2a4
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 55 deletions.
8 changes: 8 additions & 0 deletions libraries/api/types.json
Expand Up @@ -11,6 +11,14 @@
"cpp_return_type" : "bts::blockchain::blockchain_security_state",
"cpp_include_file" : "bts/blockchain/types.hpp"
},
{
"type_name" : "asset_permission",
"cpp_return_type" : "asset_permissions"
},
{
"type_name" : "asset_permission_array",
"cpp_return_type" : "std::vector<bts::blockchain::asset_permissions>"
},
{
"type_name": "float",
"cpp_return_type" : "float",
Expand Down
22 changes: 14 additions & 8 deletions libraries/api/wallet_api.json
Expand Up @@ -1627,16 +1627,22 @@
"default_value" : 0
},
{
"name" : "restricted",
"type" : "bool",
"description" : "whether or not ownership of the asset is restricted to authorized keys",
"default_value" : false
"name" : "flags",
"type" : "asset_permission_array",
"description" : "a set of flags set by the issuer (if they have permission to set them)",
"default_value" : []
},
{
"name" : "retractable",
"type" : "bool",
"description" : "whether or not issuer is a co-signer on all balances",
"default_value" : true
"name" : "issuer_permissions",
"type" : "asset_permission_array",
"description" : "a set of permissions an issuer retains",
"default_value" : ["retractable","market_halt","balance_halt","supply_limit"]
},
{
"name" : "issuer_account_name",
"type" : "account_name",
"description" : "used to transfer the asset to a new user",
"default_value" : ""
},
{
"name" : "required_sigs",
Expand Down
52 changes: 42 additions & 10 deletions libraries/blockchain/asset_operations.cpp
Expand Up @@ -169,7 +169,8 @@ namespace bts { namespace blockchain {
// Cannot update max share supply, or precision if any shares have been issued
if( current_asset_record->current_share_supply > 0 )
{
FC_ASSERT( !this->maximum_share_supply.valid() );
if( !(current_asset_record->flags & supply_unlimit) )
FC_ASSERT( !this->maximum_share_supply.valid() );
FC_ASSERT( !this->precision.valid() );
}

Expand Down Expand Up @@ -208,18 +209,49 @@ namespace bts { namespace blockchain {

if( !current_asset_record->is_market_issued() )
{
if( this->restricted ) FC_ASSERT( current_asset_record->current_share_supply == 0 );

current_asset_record->restricted = this->restricted;
if( current_asset_record->retractable )

// you can only remove these permissions, but not add them if there are current shares
if( current_asset_record->current_share_supply > 0 )
{
current_asset_record->retractable = this->retractable;
if( this->issuer_permissions & retractable )
FC_ASSERT( current_asset_record->issuer_permissions & retractable );
if( this->issuer_permissions & restricted )
FC_ASSERT( current_asset_record->issuer_permissions & restricted );
if( this->issuer_permissions & market_halt )
FC_ASSERT( current_asset_record->issuer_permissions & market_halt );
if( this->issuer_permissions & balance_halt )
FC_ASSERT( current_asset_record->issuer_permissions & balance_halt );
if( this->issuer_permissions & supply_unlimit )
FC_ASSERT( current_asset_record->issuer_permissions & supply_unlimit );
}
else FC_ASSERT( !this->retractable );
current_asset_record->transaction_fee = this->transaction_fee;
current_asset_record->authority = this->authority;
current_asset_record->issuer_permissions = this->issuer_permissions;

if( this->flags & restricted ) FC_ASSERT( current_asset_record->issuer_permissions & restricted );
if( this->flags & retractable ) FC_ASSERT( current_asset_record->issuer_permissions & retractable );
if( this->flags & market_halt ) FC_ASSERT( current_asset_record->issuer_permissions & market_halt );
if( this->flags & balance_halt ) FC_ASSERT( current_asset_record->issuer_permissions & balance_halt );
current_asset_record->flags = this->flags;

current_asset_record->transaction_fee = this->transaction_fee;
current_asset_record->authority = this->authority;
}

if( current_asset_record->is_market_issued() )
{
FC_ASSERT( this->issuer_account_id == asset_record::market_issued_asset );
}
else
{
FC_ASSERT( this->issuer_account_id != asset_record::market_issued_asset );
if( this->issuer_account_id != current_asset_record->issuer_account_id )
{
auto issuer_account_record = eval_state._current_state->get_account_record( this->issuer_account_id );
if( NOT issuer_account_record.valid() )
FC_CAPTURE_AND_THROW( unknown_account_id, (issuer_account_id) );
}
}

current_asset_record->issuer_account_id = this->issuer_account_id;
current_asset_record->last_update = eval_state._current_state->now();

eval_state._current_state->store_asset_record( *current_asset_record );
Expand Down Expand Up @@ -258,7 +290,7 @@ namespace bts { namespace blockchain {

if( NOT current_asset_record.valid() ) FC_CAPTURE_AND_THROW( unknown_asset_id, (this->asset_id) );

FC_ASSERT( current_asset_record->restricted );
FC_ASSERT( current_asset_record->issuer_permissions & restricted );
FC_ASSERT( current_asset_record->issuer_account_id != asset_record::market_issued_asset );

eval_state._current_state->authorize( this->asset_id, this->owner, this->meta_id );
Expand Down
12 changes: 11 additions & 1 deletion libraries/blockchain/balance_operations.cpp
Expand Up @@ -152,15 +152,25 @@ namespace bts { namespace blockchain {
if( !current_balance_record.valid() )
FC_CAPTURE_AND_THROW( unknown_balance_record, (balance_id) );


if( this->amount > current_balance_record->get_spendable_balance( eval_state._current_state->now() ).amount )
FC_CAPTURE_AND_THROW( insufficient_funds, (current_balance_record)(amount) );

auto asset_rec = eval_state._current_state->get_asset_record( current_balance_record->condition.asset_id );
FC_ASSERT( asset_rec.valid() );
bool issuer_override = asset_rec->is_retractable() && eval_state.verify_authority( asset_rec->authority );


if( !issuer_override )
{
FC_ASSERT( !asset_rec->is_balance_frozen() );
if( asset_rec->is_restricted() )
{
for(auto owner : current_balance_record->owners())
{
FC_ASSERT(eval_state._current_state->get_authorization(asset_rec->id, owner));
}
}
switch( (withdraw_condition_types)current_balance_record->condition.type )
{
case withdraw_signature_type:
Expand Down Expand Up @@ -327,7 +337,7 @@ namespace bts { namespace blockchain {

escrow_balance_record->balance -= total_released;
auto asset_rec = eval_state._current_state->get_asset_record( escrow_balance_record->condition.asset_id );
if( asset_rec->restricted )
if( asset_rec->is_restricted() )
{
FC_ASSERT( eval_state._current_state->get_authorization( escrow_balance_record->condition.asset_id, escrow_condition.receiver ) );
}
Expand Down
16 changes: 9 additions & 7 deletions libraries/blockchain/include/bts/blockchain/asset_operations.hpp
Expand Up @@ -4,6 +4,7 @@
#include <bts/blockchain/operations.hpp>
#include <bts/blockchain/account_record.hpp>
#include <bts/blockchain/types.hpp>
#include <bts/blockchain/asset_record.hpp>

namespace bts { namespace blockchain {

Expand Down Expand Up @@ -76,17 +77,17 @@ namespace bts { namespace blockchain {
struct update_asset_ext_operation : public update_asset_operation
{
static const operation_type_enum type;
update_asset_ext_operation(){}
update_asset_ext_operation( const update_asset_operation& c ):update_asset_operation(c){}

/**
* A restricted asset can only be held/controlled by keys
* on the authorized list.
*/
bool restricted = false;
uint32_t flags = none;
uint32_t issuer_permissions = default_permissions;
account_id_type issuer_account_id;

/**
* Asset is retractable by the issuer.
*/
bool retractable = true;

/**
* The issuer can specify a transaction fee (of the asset type)
Expand Down Expand Up @@ -161,8 +162,9 @@ FC_REFLECT( bts::blockchain::update_asset_operation,
)
FC_REFLECT_DERIVED( bts::blockchain::update_asset_ext_operation,
(bts::blockchain::update_asset_operation),
(restricted)
(retractable)
(flags)
(issuer_permissions)
(issuer_account_id)
(transaction_fee)
(authority) )

Expand Down
39 changes: 24 additions & 15 deletions libraries/blockchain/include/bts/blockchain/asset_record.hpp
Expand Up @@ -5,6 +5,18 @@

namespace bts { namespace blockchain {

enum asset_permissions
{
none = 0,
retractable = 0x01, ///<! The issuer can sign inplace of the owner
restricted = 0x02, ///<! The issuer whitelists public keys
market_halt = 0x04, ///<! The issuer can/did freeze all markets
balance_halt = 0x08, ///<! The issuer can/did freeze all balances
supply_unlimit = 0x10, ///<! The issuer can change the supply at will
default_permissions = retractable | market_halt | balance_halt | supply_unlimit,
all_permissions = 0xff
};

struct asset_record
{
enum
Expand All @@ -20,8 +32,11 @@ namespace bts { namespace blockchain {
bool is_null()const;
/** the asset is issued by the market and not by any user */
bool is_market_issued()const;
bool is_retractable()const { return !is_market_issued() && retractable; }
bool is_restricted()const { return !is_market_issued() && restricted; }
bool is_retractable()const { return !is_market_issued() && (flags & retractable); }
bool is_restricted()const { return !is_market_issued() && (flags & restricted); }
bool is_market_frozen()const { return !is_market_issued() && (flags & market_halt); }
bool is_balance_frozen()const { return !is_market_issued() && (flags & balance_halt); }
bool is_supply_unlimited()const { return !is_market_issued() && (flags & supply_unlimit); }
asset_record make_null()const;

uint64_t get_precision()const;
Expand All @@ -38,17 +53,8 @@ namespace bts { namespace blockchain {
share_type current_share_supply = 0;
share_type maximum_share_supply = 0;
share_type collected_fees = 0;
/**
* A restricted asset can only be held/controlled by keys
* on the authorized list.
*/
bool restricted = false;
/**
* Asset is retractable by the issuer, makes the asset authority
* and implicit co-signer on all balances that involve this asset.
*/
bool retractable = true;

uint32_t issuer_permissions = default_permissions;
uint32_t flags = retractable;
/**
* The issuer can specify a transaction fee (of the asset type)
* that will be paid to the issuer with every transaction that
Expand All @@ -64,6 +70,9 @@ namespace bts { namespace blockchain {

} } // bts::blockchain

FC_REFLECT_ENUM( bts::blockchain::asset_permissions,
(none)(retractable)(restricted)(market_halt)(balance_halt)(supply_unlimit)(all_permissions)(default_permissions) )

FC_REFLECT( bts::blockchain::asset_record,
(id)
(symbol)
Expand All @@ -77,8 +86,8 @@ FC_REFLECT( bts::blockchain::asset_record,
(current_share_supply)
(maximum_share_supply)
(collected_fees)
(restricted)
(retractable)
(issuer_permissions)
(flags)
(transaction_fee)
(authority)
)
4 changes: 3 additions & 1 deletion libraries/blockchain/include/bts/blockchain/operations.hpp
Expand Up @@ -64,7 +64,8 @@ namespace bts { namespace blockchain {

set_object_op_type = 28,
authorize_op_type = 29,
update_asset_ext_op_type = 30
update_asset_ext_op_type = 30,
cancel_order_op_type = 31 /** TODO: return funds to balance with same key as order */
};

/**
Expand Down Expand Up @@ -149,6 +150,7 @@ FC_REFLECT_ENUM( bts::blockchain::operation_type_enum,
(set_object_op_type)
(authorize_op_type)
(update_asset_ext_op_type)
(cancel_order_op_type)
)

FC_REFLECT( bts::blockchain::operation, (type)(data) )
Expand Down
14 changes: 14 additions & 0 deletions libraries/blockchain/include/bts/blockchain/transaction.hpp
Expand Up @@ -122,6 +122,20 @@ namespace bts { namespace blockchain {
const optional<double>& maximum_share_supply,
const optional<uint64_t>& precision );

void update_asset_ext( const asset_id_type& asset_id,
const optional<string>& name,
const optional<string>& description,
const optional<variant>& public_data,
const optional<double>& maximum_share_supply,
const optional<uint64_t>& precision,
const share_type& issuer_fee,
uint32_t issuer_permissions,
uint32_t flags,
account_id_type issuer_account_id,
uint32_t required_sigs,
const vector<address>& authority
);

void burn( const asset& quantity,
account_id_type for_or_against,
const string& public_message,
Expand Down
3 changes: 3 additions & 0 deletions libraries/blockchain/market_engine.cpp
Expand Up @@ -39,7 +39,10 @@ namespace bts { namespace blockchain { namespace detail {

oasset_record quote_asset = _pending_state->get_asset_record( _quote_id );
oasset_record base_asset = _pending_state->get_asset_record( _base_id );

FC_ASSERT( quote_asset.valid() && base_asset.valid() );
FC_ASSERT( !quote_asset->is_market_frozen() );
FC_ASSERT( !base_asset->is_market_frozen() );

// The order book is sorted from low to high price. So to get the last item (highest bid),
// we need to go to the first item in the next market class and then back up one
Expand Down
3 changes: 3 additions & 0 deletions libraries/blockchain/market_operations.cpp
Expand Up @@ -33,6 +33,8 @@ namespace bts { namespace blockchain {
if( !issuer_override && !eval_state.check_signature( owner ) )
FC_CAPTURE_AND_THROW( missing_signature, (bid_index.owner) );

FC_ASSERT( !issuer_override && !quote_asset_rec->is_balance_frozen() );

asset delta_amount = this->get_amount();

eval_state.validate_asset( delta_amount );
Expand Down Expand Up @@ -148,6 +150,7 @@ namespace bts { namespace blockchain {
if( !issuer_override && !eval_state.check_signature( owner ) )
FC_CAPTURE_AND_THROW( missing_signature, (ask_index.owner) );

FC_ASSERT( !issuer_override && !base_asset_rec->is_balance_frozen() );

asset delta_amount = this->get_amount();

Expand Down
25 changes: 25 additions & 0 deletions libraries/blockchain/transaction.cpp
Expand Up @@ -317,6 +317,31 @@ namespace bts { namespace blockchain {
{
operations.push_back( update_asset_operation{ asset_id, name, description, public_data, maximum_share_supply, precision } );
}
void transaction::update_asset_ext( const asset_id_type& asset_id,
const optional<string>& name,
const optional<string>& description,
const optional<variant>& public_data,
const optional<double>& maximum_share_supply,
const optional<uint64_t>& precision,
const share_type& issuer_fee,
uint32_t issuer_permissions,
uint32_t flags,
account_id_type issuer_account_id,
uint32_t required_sigs,
const vector<address>& authority
)
{
multisig_meta_info auth_info;
auth_info.required = required_sigs;
auth_info.owners.insert( authority.begin(), authority.end() );
update_asset_ext_operation op( update_asset_operation{asset_id, name, description, public_data, maximum_share_supply, precision} );
op.flags = flags;
op.issuer_permissions = issuer_permissions;
op.issuer_account_id = issuer_account_id;
op.transaction_fee = issuer_fee,
op.authority = auth_info;
operations.push_back( op );
}

void transaction::issue( const asset& amount_to_issue )
{
Expand Down

0 comments on commit fcbb2a4

Please sign in to comment.