BitShares-Core  4.0.0
BitShares blockchain implementation and command-line interface software
asset_object.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cryptonomex, Inc., and contributors.
3  *
4  * The MIT License
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22  * THE SOFTWARE.
23  */
26 #include <graphene/chain/hardfork.hpp>
27 
28 #include <fc/io/raw.hpp>
29 #include <fc/uint128.hpp>
30 
31 using namespace graphene::chain;
32 
34 {
36  return 0;
38  return current_supply + force_settled_volume;
39 
40  fc::uint128_t volume = current_supply.value;
41  volume += force_settled_volume.value;
43  volume /= GRAPHENE_100_PERCENT;
44  return static_cast<uint64_t>(volume);
45 }
46 
48  time_point_sec next_maintenance_time )
49 {
50  bool after_core_hardfork_1270 = ( next_maintenance_time > HARDFORK_CORE_1270_TIME ); // call price caching issue
51  current_feed_publication_time = current_time;
52  vector<std::reference_wrapper<const price_feed_with_icr>> current_feeds;
53  // find feeds that were alive at current_time
54  for( const pair<account_id_type, pair<time_point_sec,price_feed_with_icr>>& f : feeds )
55  {
56  if( (current_time - f.second.first).to_seconds() < options.feed_lifetime_sec &&
57  f.second.first != time_point_sec() )
58  {
59  current_feeds.emplace_back(f.second.second);
61  }
62  }
63 
64  // If there are no valid feeds, or the number available is less than the minimum to calculate a median...
65  if( current_feeds.size() < options.minimum_feeds )
66  {
67  //... don't calculate a median, and set a null feed
68  feed_cer_updated = false; // new median cer is null, won't update asset_object anyway, set to false for better performance
69  current_feed_publication_time = current_time;
71  if( after_core_hardfork_1270 )
72  {
73  // update data derived from MCR, ICR and etc
74  refresh_cache();
75  }
76  return;
77  }
78  if( current_feeds.size() == 1 )
79  {
80  if( current_feed.core_exchange_rate != current_feeds.front().get().core_exchange_rate )
81  feed_cer_updated = true;
82  current_feed = current_feeds.front();
83  // Note: perhaps can defer updating current_maintenance_collateralization for better performance
84  if( after_core_hardfork_1270 )
85  {
86  const auto& exts = options.extensions.value;
87  if( exts.maintenance_collateral_ratio.valid() )
88  current_feed.maintenance_collateral_ratio = *exts.maintenance_collateral_ratio;
89  if( exts.maximum_short_squeeze_ratio.valid() )
90  current_feed.maximum_short_squeeze_ratio = *exts.maximum_short_squeeze_ratio;
91  if( exts.initial_collateral_ratio.valid() )
92  current_feed.initial_collateral_ratio = *exts.initial_collateral_ratio;
93  // update data derived from MCR, ICR and etc
94  refresh_cache();
95  }
96  return;
97  }
98 
99  // *** Begin Median Calculations ***
100  price_feed_with_icr median_feed;
101  const auto median_itr = current_feeds.begin() + current_feeds.size() / 2;
102 #define CALCULATE_MEDIAN_VALUE(r, data, field_name) \
103  std::nth_element( current_feeds.begin(), median_itr, current_feeds.end(), \
104  [](const price_feed_with_icr& a, const price_feed_with_icr& b) { \
105  return a.field_name < b.field_name; \
106  }); \
107  median_feed.field_name = median_itr->get().field_name;
108 
109 #define CHECK_AND_CALCULATE_MEDIAN_VALUE(r, data, field_name) \
110  if( options.extensions.value.field_name.valid() ) { \
111  median_feed.field_name = *options.extensions.value.field_name; \
112  } else { \
113  CALCULATE_MEDIAN_VALUE(r, data, field_name); \
114  }
115 
116  BOOST_PP_SEQ_FOR_EACH( CALCULATE_MEDIAN_VALUE, ~, (settlement_price)(core_exchange_rate) )
117  BOOST_PP_SEQ_FOR_EACH( CHECK_AND_CALCULATE_MEDIAN_VALUE, ~,
118  (maintenance_collateral_ratio)(maximum_short_squeeze_ratio)(initial_collateral_ratio) )
119 #undef CHECK_AND_CALCULATE_MEDIAN_VALUE
120 #undef CALCULATE_MEDIAN_VALUE
121  // *** End Median Calculations ***
122 
124  feed_cer_updated = true;
125  current_feed = median_feed;
126  // Note: perhaps can defer updating current_maintenance_collateralization for better performance
127  if( after_core_hardfork_1270 )
128  {
129  // update data derived from MCR, ICR and etc
130  refresh_cache();
131  }
132 }
133 
135 {
139  else // if ICR is not above MCR
141 }
142 
144 {
145  if( settlement_price.is_null() )
146  return price();
147  return ~settlement_price * ratio_type( initial_collateral_ratio, GRAPHENE_COLLATERAL_RATIO_DENOM );
148 }
149 
150 asset asset_object::amount_from_string(string amount_string) const
151 { try {
152  bool negative_found = false;
153  bool decimal_found = false;
154  for( const char c : amount_string )
155  {
156  if( isdigit( c ) )
157  continue;
158 
159  if( c == '-' && !negative_found )
160  {
161  negative_found = true;
162  continue;
163  }
164 
165  if( c == '.' && !decimal_found )
166  {
167  decimal_found = true;
168  continue;
169  }
170 
171  FC_THROW( (amount_string) );
172  }
173 
174  share_type satoshis = 0;
175 
176  share_type scaled_precision = asset::scaled_precision( precision );
177 
178  const auto decimal_pos = amount_string.find( '.' );
179  const string lhs = amount_string.substr( negative_found, decimal_pos );
180  if( !lhs.empty() )
181  satoshis += fc::safe<int64_t>(std::stoll(lhs)) *= scaled_precision;
182 
183  if( decimal_found )
184  {
185  const size_t max_rhs_size = std::to_string( scaled_precision.value ).substr( 1 ).size();
186 
187  string rhs = amount_string.substr( decimal_pos + 1 );
188  FC_ASSERT( rhs.size() <= max_rhs_size );
189 
190  while( rhs.size() < max_rhs_size )
191  rhs += '0';
192 
193  if( !rhs.empty() )
194  satoshis += std::stoll( rhs );
195  }
196 
197  FC_ASSERT( satoshis <= GRAPHENE_MAX_SHARE_SUPPLY );
198 
199  if( negative_found )
200  satoshis *= -1;
201 
202  return amount(satoshis);
203 } FC_CAPTURE_AND_RETHROW( (amount_string) ) }
204 
206 {
207  share_type scaled_precision = asset::scaled_precision( precision );
208 
209  string result = fc::to_string(amount.value / scaled_precision.value);
210  auto decimals = abs( amount.value % scaled_precision.value );
211  if( decimals )
212  {
213  if( amount < 0 && result == "0" )
214  result = "-0";
215  result += "." + fc::to_string(scaled_precision.value + decimals).erase(0,1);
216  }
217  return result;
218 }
219 
221  (current_supply)(confidential_supply)(accumulated_fees)(accumulated_collateral_fees)(fee_pool) )
222 
224  (asset_id)
225  (feeds)
226  (current_feed)
230  (options)
237  )
238 
240 
share_type max_force_settlement_volume(share_type current_supply) const
Calculate the maximum force settlement volume per maintenance interval, given the current share suppl...
#define CALCULATE_MEDIAN_VALUE(r, data, field_name)
#define GRAPHENE_COLLATERAL_RATIO_DENOM
Definition: config.hpp:113
asset_id_type asset_id
The asset this object belong to.
uint16_t maximum_short_squeeze_ratio
Definition: asset.hpp:193
contains properties that only apply to bitassets (market issued assets)
share_type force_settled_volume
This is the volume of this asset which has been force-settled this maintanence interval.
boost::rational< int32_t > ratio_type
Definition: types.hpp:133
#define FC_REFLECT_DERIVED_NO_TYPENAME(TYPE, INHERITS, MEMBERS)
Definition: reflect.hpp:356
#define FC_THROW(...)
Definition: exception.hpp:366
defines market parameters for margin positions, extended with an initial_collateral_ratio field ...
#define CHECK_AND_CALCULATE_MEDIAN_VALUE(r, data, field_name)
asset amount_from_string(string amount_string) const
bool is_null() const
Definition: asset.cpp:225
#define GRAPHENE_MAX_SHARE_SUPPLY
Definition: config.hpp:38
string amount_to_string(share_type amount) const
Convert an asset to a textual representation, i.e. "123.45".
bool is_prediction_market
True if this asset implements a Prediction Market.
void update_median_feeds(time_point_sec current_time, time_point_sec next_maintenance_time)
price maintenance_collateralization() const
Definition: asset.cpp:321
bool feed_cer_updated
Track whether core exchange rate in current feed has updated.
uint16_t maintenance_collateral_ratio
Definition: asset.hpp:190
price calculate_initial_collateralization() const
The price struct stores asset prices in the BitShares system.
Definition: asset.hpp:114
#define GRAPHENE_100_PERCENT
Definition: config.hpp:102
uint8_t minimum_feeds
Minimum number of unexpired feeds required to extract a median feed from.
Definition: asset_ops.hpp:128
#define FC_CAPTURE_AND_RETHROW(...)
Definition: exception.hpp:478
#define FC_ASSERT(TEST,...)
Checks a condition and throws an assert_exception if the test is FALSE.
Definition: exception.hpp:345
tracks the asset information that changes frequentlyBecause the asset_object is very large it doesn&#39;t...
#define GRAPHENE_IMPLEMENT_EXTERNAL_SERIALIZATION(type)
Definition: types.hpp:74
uint32_t feed_lifetime_sec
Time before a price feed expires.
Definition: asset_ops.hpp:126
tracks the parameters of an assetAll assets have a globally unique symbol name that controls how they...
std::string to_string(double)
Definition: string.cpp:73
bitasset_options options
The tunable options for BitAssets are stored in this field.
base for all database objects
Definition: object.hpp:62
flat_map< account_id_type, pair< time_point_sec, price_feed_with_icr > > feeds
static share_type scaled_precision(uint8_t precision)
Definition: asset.hpp:93
bool asset_cer_updated
Track whether core_exchange_rate in corresponding asset_object has updated.
time_point_sec current_feed_publication_time
This is the publication time of the oldest feed which was factored into current_feed.
share_type settlement_fund
Amount of collateral which is available for force settlement.
T value
Definition: safe.hpp:22
price core_exchange_rate
Price at which automatically exchanging this asset for CORE from fee pool occurs (used for paying fee...
Definition: asset.hpp:187