hive-nectar 0.0.11__py3-none-any.whl → 0.1.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of hive-nectar might be problematic. Click here for more details.
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/METADATA +10 -11
- hive_nectar-0.1.0.dist-info/RECORD +88 -0
- nectar/__init__.py +1 -4
- nectar/account.py +791 -685
- nectar/amount.py +82 -21
- nectar/asset.py +1 -2
- nectar/block.py +34 -22
- nectar/blockchain.py +111 -143
- nectar/blockchaininstance.py +396 -247
- nectar/blockchainobject.py +33 -5
- nectar/cli.py +1058 -1349
- nectar/comment.py +313 -181
- nectar/community.py +39 -43
- nectar/constants.py +1 -14
- nectar/discussions.py +793 -139
- nectar/hive.py +137 -77
- nectar/hivesigner.py +106 -68
- nectar/imageuploader.py +33 -23
- nectar/instance.py +31 -79
- nectar/market.py +128 -264
- nectar/memo.py +40 -13
- nectar/message.py +23 -10
- nectar/nodelist.py +115 -81
- nectar/price.py +80 -61
- nectar/profile.py +6 -3
- nectar/rc.py +45 -25
- nectar/snapshot.py +285 -163
- nectar/storage.py +16 -5
- nectar/transactionbuilder.py +132 -41
- nectar/utils.py +37 -17
- nectar/version.py +1 -1
- nectar/vote.py +171 -30
- nectar/wallet.py +26 -19
- nectar/witness.py +153 -54
- nectarapi/graphenerpc.py +147 -133
- nectarapi/noderpc.py +12 -6
- nectarapi/rpcutils.py +12 -6
- nectarapi/version.py +1 -1
- nectarbase/ledgertransactions.py +24 -1
- nectarbase/objects.py +17 -6
- nectarbase/operations.py +160 -90
- nectarbase/signedtransactions.py +38 -2
- nectarbase/version.py +1 -1
- nectargraphenebase/account.py +295 -17
- nectargraphenebase/chains.py +0 -135
- nectargraphenebase/ecdsasig.py +152 -176
- nectargraphenebase/types.py +18 -4
- nectargraphenebase/unsignedtransactions.py +1 -1
- nectargraphenebase/version.py +1 -1
- hive_nectar-0.0.11.dist-info/RECORD +0 -91
- nectar/blurt.py +0 -562
- nectar/conveyor.py +0 -308
- nectar/steem.py +0 -581
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/WHEEL +0 -0
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/entry_points.txt +0 -0
- {hive_nectar-0.0.11.dist-info → hive_nectar-0.1.0.dist-info}/licenses/LICENSE.txt +0 -0
nectar/snapshot.py
CHANGED
|
@@ -2,12 +2,13 @@
|
|
|
2
2
|
import json
|
|
3
3
|
import logging
|
|
4
4
|
import re
|
|
5
|
+
import warnings
|
|
5
6
|
from bisect import bisect_left
|
|
6
7
|
from datetime import date, datetime, time, timedelta, timezone
|
|
7
8
|
|
|
8
9
|
from nectar.account import Account
|
|
9
10
|
from nectar.amount import Amount
|
|
10
|
-
from nectar.constants import
|
|
11
|
+
from nectar.constants import HIVE_100_PERCENT, HIVE_VOTE_REGENERATION_SECONDS
|
|
11
12
|
from nectar.instance import shared_blockchain_instance
|
|
12
13
|
from nectar.utils import (
|
|
13
14
|
addTzInfo,
|
|
@@ -24,30 +25,53 @@ class AccountSnapshot(list):
|
|
|
24
25
|
"""This class allows to easily access Account history
|
|
25
26
|
|
|
26
27
|
:param str account_name: Name of the account
|
|
27
|
-
:param
|
|
28
|
-
instance
|
|
28
|
+
:param Hive blockchain_instance: Hive instance
|
|
29
29
|
"""
|
|
30
30
|
|
|
31
|
-
def __init__(self, account, account_history=
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
def __init__(self, account, account_history=None, blockchain_instance=None, **kwargs):
|
|
32
|
+
super(AccountSnapshot, self).__init__(account_history or [])
|
|
33
|
+
# Warn about any unused kwargs to maintain backward compatibility
|
|
34
|
+
"""
|
|
35
|
+
Initialize an AccountSnapshot for the given account.
|
|
36
|
+
|
|
37
|
+
Creates an Account object for the target account (using the provided blockchain instance or the shared instance), resets internal snapshot state, and populates the snapshot list with any provided account_history. Any unexpected keyword arguments are accepted but ignored; a DeprecationWarning is emitted for each.
|
|
38
|
+
|
|
39
|
+
Parameters:
|
|
40
|
+
account (str or Account): Account identifier or existing Account object to build the snapshot for.
|
|
41
|
+
account_history (iterable, optional): Pre-fetched sequence of account operations to initialize the snapshot with. Defaults to an empty list.
|
|
42
|
+
|
|
43
|
+
Notes:
|
|
44
|
+
- blockchain_instance is accepted but not documented here as a service-like parameter; if provided it overrides the shared blockchain instance used to construct the Account.
|
|
45
|
+
- This initializer mutates internal state (calls reset) and appends account_history into the snapshot's underlying list.
|
|
46
|
+
"""
|
|
47
|
+
if kwargs:
|
|
48
|
+
for key in kwargs:
|
|
49
|
+
warnings.warn(
|
|
50
|
+
f"Unexpected keyword argument '{key}' passed to AccountSnapshot.__init__. "
|
|
51
|
+
"This may be a deprecated parameter and will be ignored.",
|
|
52
|
+
DeprecationWarning,
|
|
53
|
+
stacklevel=2,
|
|
54
|
+
)
|
|
37
55
|
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
38
56
|
self.account = Account(account, blockchain_instance=self.blockchain)
|
|
39
57
|
self.reset()
|
|
40
58
|
super(AccountSnapshot, self).__init__(account_history)
|
|
41
59
|
|
|
42
60
|
def reset(self):
|
|
43
|
-
"""
|
|
61
|
+
"""
|
|
62
|
+
Reset internal time-series and aggregation arrays while preserving the stored account history.
|
|
63
|
+
|
|
64
|
+
Reinitializes per-timestamp state used to build derived metrics (vesting, Hive/HBD balances, delegations,
|
|
65
|
+
operation statistics, reward and vote timelines, reputation and voting-power arrays). Does not modify
|
|
66
|
+
the list contents (the stored raw account history).
|
|
67
|
+
"""
|
|
44
68
|
self.own_vests = [
|
|
45
69
|
Amount(0, self.blockchain.vest_token_symbol, blockchain_instance=self.blockchain)
|
|
46
70
|
]
|
|
47
|
-
self.
|
|
71
|
+
self.own_hive = [
|
|
48
72
|
Amount(0, self.blockchain.token_symbol, blockchain_instance=self.blockchain)
|
|
49
73
|
]
|
|
50
|
-
self.
|
|
74
|
+
self.own_hbd = [
|
|
51
75
|
Amount(0, self.blockchain.backed_token_symbol, blockchain_instance=self.blockchain)
|
|
52
76
|
]
|
|
53
77
|
self.delegated_vests_in = [{}]
|
|
@@ -59,8 +83,8 @@ class AccountSnapshot(list):
|
|
|
59
83
|
self.reward_timestamps = []
|
|
60
84
|
self.author_rewards = []
|
|
61
85
|
self.curation_rewards = []
|
|
62
|
-
self.
|
|
63
|
-
self.
|
|
86
|
+
self.curation_per_1000_HP_timestamp = []
|
|
87
|
+
self.curation_per_1000_HP = []
|
|
64
88
|
self.out_vote_timestamp = []
|
|
65
89
|
self.out_vote_weight = []
|
|
66
90
|
self.in_vote_timestamp = []
|
|
@@ -136,7 +160,22 @@ class AccountSnapshot(list):
|
|
|
136
160
|
yield op
|
|
137
161
|
|
|
138
162
|
def get_data(self, timestamp=None, index=0):
|
|
139
|
-
"""
|
|
163
|
+
"""
|
|
164
|
+
Return a dictionary snapshot of the account state at or immediately before the given timestamp.
|
|
165
|
+
|
|
166
|
+
If timestamp is None the current UTC time is used. The timestamp is normalized to a timezone-aware UTC value. The method finds the most recent stored tick whose timestamp is <= the requested time and returns a dict with the corresponding state:
|
|
167
|
+
- "timestamp": stored timestamp used
|
|
168
|
+
- "vests": own vesting shares at that tick
|
|
169
|
+
- "delegated_vests_in": mapping of incoming delegations at that tick
|
|
170
|
+
- "delegated_vests_out": mapping of outgoing delegations at that tick
|
|
171
|
+
- "sp_own": Hive Power equivalent of own vests at that tick
|
|
172
|
+
- "sp_eff": effective Hive Power (own + delegated_in - delegated_out) at that tick
|
|
173
|
+
- "hive": liquid HIVE balance at that tick
|
|
174
|
+
- "hbd": liquid HBD balance at that tick
|
|
175
|
+
- "index": index into the internal arrays for that tick
|
|
176
|
+
|
|
177
|
+
Returns an empty dict if the requested timestamp is earlier than the earliest stored timestamp.
|
|
178
|
+
"""
|
|
140
179
|
if timestamp is None:
|
|
141
180
|
timestamp = datetime.now(timezone.utc)
|
|
142
181
|
timestamp = addTzInfo(timestamp)
|
|
@@ -150,20 +189,13 @@ class AccountSnapshot(list):
|
|
|
150
189
|
own = self.own_vests[index]
|
|
151
190
|
din = self.delegated_vests_in[index]
|
|
152
191
|
dout = self.delegated_vests_out[index]
|
|
153
|
-
|
|
154
|
-
|
|
192
|
+
hive = self.own_hive[index]
|
|
193
|
+
hbd = self.own_hbd[index]
|
|
155
194
|
sum_in = sum([din[key].amount for key in din])
|
|
156
195
|
sum_out = sum([dout[key].amount for key in dout])
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
sp_in = self.blockchain.vests_to_sp(sum_in, timestamp=ts)
|
|
161
|
-
sp_out = self.blockchain.vests_to_sp(sum_out, timestamp=ts)
|
|
162
|
-
sp_own = self.blockchain.vests_to_sp(own, timestamp=ts)
|
|
163
|
-
else:
|
|
164
|
-
sp_in = self.blockchain.vests_to_hp(sum_in, timestamp=ts)
|
|
165
|
-
sp_out = self.blockchain.vests_to_hp(sum_out, timestamp=ts)
|
|
166
|
-
sp_own = self.blockchain.vests_to_hp(own, timestamp=ts)
|
|
196
|
+
sp_in = self.blockchain.vests_to_hp(sum_in, timestamp=ts)
|
|
197
|
+
sp_out = self.blockchain.vests_to_hp(sum_out, timestamp=ts)
|
|
198
|
+
sp_own = self.blockchain.vests_to_hp(own, timestamp=ts)
|
|
167
199
|
sp_eff = sp_own + sp_in - sp_out
|
|
168
200
|
return {
|
|
169
201
|
"timestamp": ts,
|
|
@@ -172,40 +204,76 @@ class AccountSnapshot(list):
|
|
|
172
204
|
"delegated_vests_out": dout,
|
|
173
205
|
"sp_own": sp_own,
|
|
174
206
|
"sp_eff": sp_eff,
|
|
175
|
-
"
|
|
176
|
-
"
|
|
207
|
+
"hive": hive,
|
|
208
|
+
"hbd": hbd,
|
|
177
209
|
"index": index,
|
|
178
210
|
}
|
|
179
211
|
|
|
180
212
|
def get_account_history(self, start=None, stop=None, use_block_num=True):
|
|
181
|
-
"""
|
|
182
|
-
|
|
183
|
-
:param start: start number/date of transactions to
|
|
184
|
-
return (*optional*)
|
|
185
|
-
:type start: int, datetime
|
|
186
|
-
:param stop: stop number/date of transactions to
|
|
187
|
-
return (*optional*)
|
|
188
|
-
:type stop: int, datetime
|
|
189
|
-
:param bool use_block_num: if true, start and stop are block numbers,
|
|
190
|
-
otherwise virtual OP count numbers.
|
|
213
|
+
"""
|
|
214
|
+
Populate the snapshot with the account's history between start and stop.
|
|
191
215
|
|
|
216
|
+
Fetches operations from the underlying Account.history iterator and replaces the snapshot's contents with those operations. If start/stop are provided they may be block numbers or datetimes; set use_block_num=False to interpret them as virtual operation indices/timestamps instead of block numbers.
|
|
192
217
|
"""
|
|
193
218
|
super(AccountSnapshot, self).__init__(
|
|
194
219
|
[h for h in self.account.history(start=start, stop=stop, use_block_num=use_block_num)]
|
|
195
220
|
)
|
|
196
221
|
|
|
197
|
-
def update_rewards(self, timestamp, curation_reward, author_vests,
|
|
222
|
+
def update_rewards(self, timestamp, curation_reward, author_vests, author_hive, author_hbd):
|
|
223
|
+
"""
|
|
224
|
+
Record a reward event at a given timestamp.
|
|
225
|
+
|
|
226
|
+
Appends the reward timestamp, the curation portion, and the author's reward components (vests, hive, hbd)
|
|
227
|
+
to the snapshot's internal reward arrays so they can be used by later aggregation and analysis.
|
|
228
|
+
|
|
229
|
+
Parameters:
|
|
230
|
+
timestamp (datetime or int): Event time (timezone-aware datetime or block/time integer) for the reward.
|
|
231
|
+
curation_reward (Amount or number): Curation reward amount (in vests or numeric representation used by the codebase).
|
|
232
|
+
author_vests (Amount or number): Author reward in vesting shares.
|
|
233
|
+
author_hive (Amount or number): Author reward in liquid HIVE.
|
|
234
|
+
author_hbd (Amount or number): Author reward in HBD.
|
|
235
|
+
|
|
236
|
+
Returns:
|
|
237
|
+
None
|
|
238
|
+
"""
|
|
198
239
|
self.reward_timestamps.append(timestamp)
|
|
199
240
|
self.curation_rewards.append(curation_reward)
|
|
200
|
-
self.author_rewards.append(
|
|
201
|
-
{"vests": author_vests, "steem": author_steem, "sbd": author_sbd}
|
|
202
|
-
)
|
|
241
|
+
self.author_rewards.append({"vests": author_vests, "hive": author_hive, "hbd": author_hbd})
|
|
203
242
|
|
|
204
243
|
def update_out_vote(self, timestamp, weight):
|
|
244
|
+
"""
|
|
245
|
+
Record an outbound vote event.
|
|
246
|
+
|
|
247
|
+
Appends the vote timestamp and weight to the snapshot's outbound-vote arrays for later voting-power and history calculations.
|
|
248
|
+
|
|
249
|
+
Parameters:
|
|
250
|
+
timestamp (datetime | int): Time of the vote (timezone-aware datetime or block timestamp).
|
|
251
|
+
weight (int): Vote weight as an integer (e.g., range -10000..10000).
|
|
252
|
+
"""
|
|
205
253
|
self.out_vote_timestamp.append(timestamp)
|
|
206
254
|
self.out_vote_weight.append(weight)
|
|
207
255
|
|
|
208
256
|
def update_in_vote(self, timestamp, weight, op):
|
|
257
|
+
"""
|
|
258
|
+
Record an incoming vote event by parsing a Vote operation and appending its data to the snapshot's in-vote arrays.
|
|
259
|
+
|
|
260
|
+
Parses the provided operation into a Vote, refreshes it, and on success appends:
|
|
261
|
+
- timestamp to in_vote_timestamp
|
|
262
|
+
- weight to in_vote_weight
|
|
263
|
+
- the voter's reputation to in_vote_rep (as int)
|
|
264
|
+
- the vote's rshares to in_vote_rshares (as int)
|
|
265
|
+
|
|
266
|
+
Parameters:
|
|
267
|
+
timestamp: datetime
|
|
268
|
+
Time of the vote event (should be timezone-aware).
|
|
269
|
+
weight: int
|
|
270
|
+
Vote weight as provided by the operation.
|
|
271
|
+
op:
|
|
272
|
+
Raw operation data used to construct the Vote.
|
|
273
|
+
|
|
274
|
+
Notes:
|
|
275
|
+
If the operation cannot be parsed into a valid Vote, the function prints an error message and returns without modifying the snapshot.
|
|
276
|
+
"""
|
|
209
277
|
v = Vote(op)
|
|
210
278
|
try:
|
|
211
279
|
v.refresh()
|
|
@@ -217,31 +285,38 @@ class AccountSnapshot(list):
|
|
|
217
285
|
print("Could not find: %s" % v)
|
|
218
286
|
return
|
|
219
287
|
|
|
220
|
-
def update(self, timestamp, own, delegated_in=None, delegated_out=None,
|
|
221
|
-
"""
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
:
|
|
225
|
-
|
|
226
|
-
:
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
288
|
+
def update(self, timestamp, own, delegated_in=None, delegated_out=None, hive=0, hbd=0):
|
|
289
|
+
"""
|
|
290
|
+
Update internal time-series state with a new account event.
|
|
291
|
+
|
|
292
|
+
Appends two timeline entries: a one-second "pre-tick" preserving the previous state at timestamp - 1s, then a tick at timestamp with updated balances and delegation maps. This updates the snapshot's arrays for timestamps, own vests, liquid HIVE/HBD balances, and incoming/outgoing vesting delegations.
|
|
293
|
+
|
|
294
|
+
Parameters:
|
|
295
|
+
timestamp (datetime): Event time (timezone-aware). A "pre-tick" is created at timestamp - 1s.
|
|
296
|
+
own (Amount or float): Change in the account's own vesting shares (vests) to apply at the tick.
|
|
297
|
+
delegated_in (dict or None): Incoming delegation change of form {"account": name, "amount": vests} or None.
|
|
298
|
+
If amount == 0 the delegation entry for that account is removed.
|
|
299
|
+
delegated_out (dict or None): Outgoing delegation change. Typical forms:
|
|
300
|
+
- {"account": name, "amount": vests} to add/update a non-zero outgoing delegation.
|
|
301
|
+
- {"account": None, "amount": vests} indicates a return_vesting_delegation; the matching outgoing entry with the same amount is removed.
|
|
302
|
+
If omitted or empty, outgoing delegations are unchanged.
|
|
303
|
+
hive (Amount or float): Change in liquid HIVE to apply at the tick.
|
|
304
|
+
hbd (Amount or float): Change in liquid HBD to apply at the tick.
|
|
305
|
+
|
|
306
|
+
Returns:
|
|
307
|
+
None
|
|
233
308
|
"""
|
|
234
309
|
self.timestamps.append(timestamp - timedelta(seconds=1))
|
|
235
310
|
self.own_vests.append(self.own_vests[-1])
|
|
236
|
-
self.
|
|
237
|
-
self.
|
|
311
|
+
self.own_hive.append(self.own_hive[-1])
|
|
312
|
+
self.own_hbd.append(self.own_hbd[-1])
|
|
238
313
|
self.delegated_vests_in.append(self.delegated_vests_in[-1])
|
|
239
314
|
self.delegated_vests_out.append(self.delegated_vests_out[-1])
|
|
240
315
|
|
|
241
316
|
self.timestamps.append(timestamp)
|
|
242
317
|
self.own_vests.append(self.own_vests[-1] + own)
|
|
243
|
-
self.
|
|
244
|
-
self.
|
|
318
|
+
self.own_hive.append(self.own_hive[-1] + hive)
|
|
319
|
+
self.own_hbd.append(self.own_hbd[-1] + hbd)
|
|
245
320
|
|
|
246
321
|
new_deleg = dict(self.delegated_vests_in[-1])
|
|
247
322
|
if delegated_in is not None and delegated_in:
|
|
@@ -309,33 +384,40 @@ class AccountSnapshot(list):
|
|
|
309
384
|
def parse_op(
|
|
310
385
|
self, op, only_ops=[], enable_rewards=False, enable_out_votes=False, enable_in_votes=False
|
|
311
386
|
):
|
|
312
|
-
"""
|
|
387
|
+
"""
|
|
388
|
+
Parse a single account-history operation and update the snapshot's internal state.
|
|
389
|
+
|
|
390
|
+
Parses the provided operation dictionary `op` (expects keys like "type" and "timestamp"), converts amounts using the snapshot's blockchain instance, and applies its effect to the snapshot by calling the appropriate update methods (e.g. update, update_rewards, update_out_vote, update_in_vote). Handles Hive-specific operations such as account creation, transfers, vesting/delegation, reward payouts, order fills, conversions, interest, votes, and hardfork-related adjustments. Many other operation types are intentionally ignored.
|
|
391
|
+
|
|
392
|
+
Parameters:
|
|
393
|
+
op (dict): A single operation entry from account history. Must contain a parsable "timestamp" and a "type" key; other required keys depend on the operation type.
|
|
394
|
+
only_ops (list): If non-empty, treat operations listed here as affecting balances/votes even when reward/vote-collection flags are disabled.
|
|
395
|
+
enable_rewards (bool): When True, record reward aggregates via update_rewards in addition to applying balance changes.
|
|
396
|
+
enable_out_votes (bool): When True, record outbound votes (this account as voter) via update_out_vote.
|
|
397
|
+
enable_in_votes (bool): When True, record inbound votes (this account as author/recipient) via update_in_vote.
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
None
|
|
401
|
+
"""
|
|
313
402
|
ts = parse_time(op["timestamp"])
|
|
314
403
|
|
|
315
404
|
if op["type"] == "account_create":
|
|
316
|
-
|
|
317
|
-
fee_vests = self.blockchain.
|
|
405
|
+
fee_hive = Amount(op["fee"], blockchain_instance=self.blockchain).amount
|
|
406
|
+
fee_vests = self.blockchain.hp_to_vests(
|
|
318
407
|
Amount(op["fee"], blockchain_instance=self.blockchain).amount, timestamp=ts
|
|
319
408
|
)
|
|
320
409
|
if op["new_account_name"] == self.account["name"]:
|
|
321
410
|
self.update(ts, fee_vests, 0, 0)
|
|
322
411
|
return
|
|
323
412
|
if op["creator"] == self.account["name"]:
|
|
324
|
-
self.update(ts, 0, 0, 0,
|
|
413
|
+
self.update(ts, 0, 0, 0, fee_hive * (-1), 0)
|
|
325
414
|
return
|
|
326
415
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
fee_vests = self.blockchain.sp_to_vests(
|
|
333
|
-
Amount(op["fee"], blockchain_instance=self.blockchain).amount, timestamp=ts
|
|
334
|
-
)
|
|
335
|
-
else:
|
|
336
|
-
fee_vests = self.blockchain.hp_to_vests(
|
|
337
|
-
Amount(op["fee"], blockchain_instance=self.blockchain).amount, timestamp=ts
|
|
338
|
-
)
|
|
416
|
+
if op["type"] == "account_create_with_delegation":
|
|
417
|
+
fee_hive = Amount(op["fee"], blockchain_instance=self.blockchain).amount
|
|
418
|
+
fee_vests = self.blockchain.hp_to_vests(
|
|
419
|
+
Amount(op["fee"], blockchain_instance=self.blockchain).amount, timestamp=ts
|
|
420
|
+
)
|
|
339
421
|
if op["new_account_name"] == self.account["name"]:
|
|
340
422
|
if Amount(op["delegation"], blockchain_instance=self.blockchain).amount > 0:
|
|
341
423
|
delegation = {
|
|
@@ -352,7 +434,7 @@ class AccountSnapshot(list):
|
|
|
352
434
|
"account": op["new_account_name"],
|
|
353
435
|
"amount": Amount(op["delegation"], blockchain_instance=self.blockchain),
|
|
354
436
|
}
|
|
355
|
-
self.update(ts, 0, 0, delegation,
|
|
437
|
+
self.update(ts, 0, 0, delegation, fee_hive * (-1), 0)
|
|
356
438
|
return
|
|
357
439
|
|
|
358
440
|
elif op["type"] == "delegate_vesting_shares":
|
|
@@ -370,14 +452,14 @@ class AccountSnapshot(list):
|
|
|
370
452
|
amount = Amount(op["amount"], blockchain_instance=self.blockchain)
|
|
371
453
|
if op["from"] == self.account["name"]:
|
|
372
454
|
if amount.symbol == self.blockchain.blockchain_symbol:
|
|
373
|
-
self.update(ts, 0,
|
|
455
|
+
self.update(ts, 0, None, None, hive=amount * (-1), hbd=0)
|
|
374
456
|
elif amount.symbol == self.blockchain.backed_token_symbol:
|
|
375
|
-
self.update(ts, 0,
|
|
457
|
+
self.update(ts, 0, None, None, hive=0, hbd=amount * (-1))
|
|
376
458
|
if op["to"] == self.account["name"]:
|
|
377
459
|
if amount.symbol == self.blockchain.blockchain_symbol:
|
|
378
|
-
self.update(ts, 0,
|
|
460
|
+
self.update(ts, 0, None, None, hive=amount, hbd=0)
|
|
379
461
|
elif amount.symbol == self.blockchain.backed_token_symbol:
|
|
380
|
-
self.update(ts, 0,
|
|
462
|
+
self.update(ts, 0, None, None, hive=0, hbd=amount)
|
|
381
463
|
return
|
|
382
464
|
|
|
383
465
|
elif op["type"] == "fill_order":
|
|
@@ -385,35 +467,32 @@ class AccountSnapshot(list):
|
|
|
385
467
|
open_pays = Amount(op["open_pays"], blockchain_instance=self.blockchain)
|
|
386
468
|
if op["current_owner"] == self.account["name"]:
|
|
387
469
|
if current_pays.symbol == self.blockchain.token_symbol:
|
|
388
|
-
self.update(ts, 0,
|
|
470
|
+
self.update(ts, 0, None, None, hive=current_pays * (-1), hbd=open_pays)
|
|
389
471
|
elif current_pays.symbol == self.blockchain.backed_token_symbol:
|
|
390
|
-
self.update(ts, 0,
|
|
472
|
+
self.update(ts, 0, None, None, hive=open_pays, hbd=current_pays * (-1))
|
|
391
473
|
if op["open_owner"] == self.account["name"]:
|
|
392
474
|
if current_pays.symbol == self.blockchain.token_symbol:
|
|
393
|
-
self.update(ts, 0,
|
|
475
|
+
self.update(ts, 0, None, None, hive=current_pays, hbd=open_pays * (-1))
|
|
394
476
|
elif current_pays.symbol == self.blockchain.backed_token_symbol:
|
|
395
|
-
self.update(ts, 0,
|
|
477
|
+
self.update(ts, 0, None, None, hive=open_pays * (-1), hbd=current_pays)
|
|
396
478
|
return
|
|
397
479
|
|
|
398
480
|
elif op["type"] == "transfer_to_vesting":
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if isinstance(self.blockchain, Steem):
|
|
403
|
-
vests = self.blockchain.sp_to_vests(steem.amount, timestamp=ts)
|
|
404
|
-
else:
|
|
405
|
-
vests = self.blockchain.hp_to_vests(steem.amount, timestamp=ts)
|
|
481
|
+
hive_amt = Amount(op["amount"], blockchain_instance=self.blockchain)
|
|
482
|
+
vests = self.blockchain.hp_to_vests(hive_amt.amount, timestamp=ts)
|
|
406
483
|
if op["from"] == self.account["name"] and op["to"] == self.account["name"]:
|
|
407
|
-
self.update(
|
|
484
|
+
self.update(
|
|
485
|
+
ts, vests, 0, 0, hive_amt * (-1), 0
|
|
486
|
+
) # power up from and to given account
|
|
408
487
|
elif op["from"] != self.account["name"] and op["to"] == self.account["name"]:
|
|
409
488
|
self.update(ts, vests, 0, 0, 0, 0) # power up from another account
|
|
410
489
|
else: # op['from'] == self.account["name"] and op['to'] != self.account["name"]
|
|
411
|
-
self.update(ts, 0, 0, 0,
|
|
490
|
+
self.update(ts, 0, 0, 0, hive_amt * (-1), 0) # power up to another account
|
|
412
491
|
return
|
|
413
492
|
|
|
414
493
|
elif op["type"] == "fill_vesting_withdraw":
|
|
415
494
|
vests = Amount(op["withdrawn"], blockchain_instance=self.blockchain)
|
|
416
|
-
self.update(ts, vests * (-1), 0, 0)
|
|
495
|
+
self.update(ts, vests * (-1), None, None, hive=0, hbd=0)
|
|
417
496
|
return
|
|
418
497
|
|
|
419
498
|
elif op["type"] == "return_vesting_delegation":
|
|
@@ -421,21 +500,21 @@ class AccountSnapshot(list):
|
|
|
421
500
|
"account": None,
|
|
422
501
|
"amount": Amount(op["vesting_shares"], blockchain_instance=self.blockchain),
|
|
423
502
|
}
|
|
424
|
-
self.update(ts, 0,
|
|
503
|
+
self.update(ts, 0, None, delegated_out=delegation)
|
|
425
504
|
return
|
|
426
505
|
|
|
427
506
|
elif op["type"] == "claim_reward_balance":
|
|
428
507
|
vests = Amount(op["reward_vests"], blockchain_instance=self.blockchain)
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
self.update(ts, vests,
|
|
508
|
+
hive = Amount(op["reward_hive"], blockchain_instance=self.blockchain)
|
|
509
|
+
hbd = Amount(op["reward_hbd"], blockchain_instance=self.blockchain)
|
|
510
|
+
self.update(ts, vests, None, None, hive=hive, hbd=hbd)
|
|
432
511
|
return
|
|
433
512
|
|
|
434
513
|
elif op["type"] == "curation_reward":
|
|
435
514
|
if "curation_reward" in only_ops or enable_rewards:
|
|
436
515
|
vests = Amount(op["reward"], blockchain_instance=self.blockchain)
|
|
437
516
|
if "curation_reward" in only_ops:
|
|
438
|
-
self.update(ts, vests, 0, 0)
|
|
517
|
+
self.update(ts, vests, None, None, hive=0, hbd=0)
|
|
439
518
|
if enable_rewards:
|
|
440
519
|
self.update_rewards(ts, vests, 0, 0, 0)
|
|
441
520
|
return
|
|
@@ -443,29 +522,29 @@ class AccountSnapshot(list):
|
|
|
443
522
|
elif op["type"] == "author_reward":
|
|
444
523
|
if "author_reward" in only_ops or enable_rewards:
|
|
445
524
|
vests = Amount(op["vesting_payout"], blockchain_instance=self.blockchain)
|
|
446
|
-
|
|
447
|
-
|
|
525
|
+
hive = Amount(op["hive_payout"], blockchain_instance=self.blockchain)
|
|
526
|
+
hbd = Amount(op["hbd_payout"], blockchain_instance=self.blockchain)
|
|
448
527
|
if "author_reward" in only_ops:
|
|
449
|
-
self.update(ts, vests,
|
|
528
|
+
self.update(ts, vests, None, None, hive=hive, hbd=hbd)
|
|
450
529
|
if enable_rewards:
|
|
451
|
-
self.update_rewards(ts, 0, vests,
|
|
530
|
+
self.update_rewards(ts, 0, vests, hive, hbd)
|
|
452
531
|
return
|
|
453
532
|
|
|
454
533
|
elif op["type"] == "producer_reward":
|
|
455
534
|
vests = Amount(op["vesting_shares"], blockchain_instance=self.blockchain)
|
|
456
|
-
self.update(ts, vests, 0, 0)
|
|
535
|
+
self.update(ts, vests, None, None, hive=0, hbd=0)
|
|
457
536
|
return
|
|
458
537
|
|
|
459
538
|
elif op["type"] == "comment_benefactor_reward":
|
|
460
539
|
if op["benefactor"] == self.account["name"]:
|
|
461
540
|
if "reward" in op:
|
|
462
541
|
vests = Amount(op["reward"], blockchain_instance=self.blockchain)
|
|
463
|
-
self.update(ts, vests, 0, 0)
|
|
542
|
+
self.update(ts, vests, None, None, hive=0, hbd=0)
|
|
464
543
|
else:
|
|
465
544
|
vests = Amount(op["vesting_payout"], blockchain_instance=self.blockchain)
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
self.update(ts, vests,
|
|
545
|
+
hive = Amount(op["hive_payout"], blockchain_instance=self.blockchain)
|
|
546
|
+
hbd = Amount(op["hbd_payout"], blockchain_instance=self.blockchain)
|
|
547
|
+
self.update(ts, vests, None, None, hive=hive, hbd=hbd)
|
|
469
548
|
return
|
|
470
549
|
else:
|
|
471
550
|
return
|
|
@@ -474,12 +553,12 @@ class AccountSnapshot(list):
|
|
|
474
553
|
amount_in = Amount(op["amount_in"], blockchain_instance=self.blockchain)
|
|
475
554
|
amount_out = Amount(op["amount_out"], blockchain_instance=self.blockchain)
|
|
476
555
|
if op["owner"] == self.account["name"]:
|
|
477
|
-
self.update(ts, 0,
|
|
556
|
+
self.update(ts, 0, None, None, hive=amount_out, hbd=amount_in * (-1))
|
|
478
557
|
return
|
|
479
558
|
|
|
480
559
|
elif op["type"] == "interest":
|
|
481
560
|
interest = Amount(op["interest"], blockchain_instance=self.blockchain)
|
|
482
|
-
self.update(ts, 0,
|
|
561
|
+
self.update(ts, 0, None, None, hive=0, hbd=interest)
|
|
483
562
|
return
|
|
484
563
|
|
|
485
564
|
elif op["type"] == "vote":
|
|
@@ -494,9 +573,9 @@ class AccountSnapshot(list):
|
|
|
494
573
|
|
|
495
574
|
elif op["type"] == "hardfork_hive":
|
|
496
575
|
vests = Amount(op["vests_converted"])
|
|
497
|
-
hbd = Amount(op["
|
|
498
|
-
hive = Amount(op["
|
|
499
|
-
self.update(ts, vests * (-1),
|
|
576
|
+
hbd = Amount(op["hbd_transferred"])
|
|
577
|
+
hive = Amount(op["hive_transferred"])
|
|
578
|
+
self.update(ts, vests * (-1), None, None, hive=hive * (-1), hbd=hbd * (-1))
|
|
500
579
|
|
|
501
580
|
elif op["type"] in [
|
|
502
581
|
"comment",
|
|
@@ -522,7 +601,19 @@ class AccountSnapshot(list):
|
|
|
522
601
|
return
|
|
523
602
|
|
|
524
603
|
def build_sp_arrays(self):
|
|
525
|
-
"""
|
|
604
|
+
"""
|
|
605
|
+
Build timelines of own and effective Hive Power (HP) for each stored timestamp.
|
|
606
|
+
|
|
607
|
+
For every timestamp in the snapshot, convert the account's own vesting shares and the
|
|
608
|
+
sum of delegated-in/out vesting shares to Hive Power via the blockchain's
|
|
609
|
+
`vests_to_hp` conversion and populate:
|
|
610
|
+
- self.own_sp: HP equivalent of the account's own vesting shares at each timestamp.
|
|
611
|
+
- self.eff_sp: effective HP = own HP + HP delegated in - HP delegated out at each timestamp.
|
|
612
|
+
|
|
613
|
+
This method mutates self.own_sp and self.eff_sp in-place and relies on
|
|
614
|
+
self.timestamps, self.own_vests, self.delegated_vests_in, self.delegated_vests_out,
|
|
615
|
+
and self.blockchain.vests_to_hp(timestamp=...).
|
|
616
|
+
"""
|
|
526
617
|
self.own_sp = []
|
|
527
618
|
self.eff_sp = []
|
|
528
619
|
for ts, own, din, dout in zip(
|
|
@@ -530,16 +621,9 @@ class AccountSnapshot(list):
|
|
|
530
621
|
):
|
|
531
622
|
sum_in = sum([din[key].amount for key in din])
|
|
532
623
|
sum_out = sum([dout[key].amount for key in dout])
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
sp_in = self.blockchain.vests_to_sp(sum_in, timestamp=ts)
|
|
537
|
-
sp_out = self.blockchain.vests_to_sp(sum_out, timestamp=ts)
|
|
538
|
-
sp_own = self.blockchain.vests_to_sp(own, timestamp=ts)
|
|
539
|
-
else:
|
|
540
|
-
sp_in = self.blockchain.vests_to_hp(sum_in, timestamp=ts)
|
|
541
|
-
sp_out = self.blockchain.vests_to_hp(sum_out, timestamp=ts)
|
|
542
|
-
sp_own = self.blockchain.vests_to_hp(own, timestamp=ts)
|
|
624
|
+
sp_in = self.blockchain.vests_to_hp(sum_in, timestamp=ts)
|
|
625
|
+
sp_out = self.blockchain.vests_to_hp(sum_out, timestamp=ts)
|
|
626
|
+
sp_own = self.blockchain.vests_to_hp(own, timestamp=ts)
|
|
543
627
|
|
|
544
628
|
sp_eff = sp_own + sp_in - sp_out
|
|
545
629
|
self.own_sp.append(sp_own)
|
|
@@ -558,30 +642,45 @@ class AccountSnapshot(list):
|
|
|
558
642
|
self.rep_timestamp.append(ts)
|
|
559
643
|
|
|
560
644
|
def build_vp_arrays(self):
|
|
561
|
-
"""
|
|
645
|
+
"""
|
|
646
|
+
Build timelines for upvote and downvote voting power.
|
|
647
|
+
|
|
648
|
+
Populates the following instance arrays with parallel timestamps and voting-power values:
|
|
649
|
+
- self.vp_timestamp, self.vp: upvoting power timeline
|
|
650
|
+
- self.downvote_vp_timestamp, self.downvote_vp: downvoting power timeline
|
|
651
|
+
|
|
652
|
+
The method iterates over recorded outgoing votes (self.out_vote_timestamp / self.out_vote_weight),
|
|
653
|
+
applies Hive vote-regeneration rules (using HIVE_VOTE_REGENERATION_SECONDS and HIVE_100_PERCENT),
|
|
654
|
+
accounts for the HF_21 downvote timing change, and models vote drains via the blockchain's
|
|
655
|
+
_vote/resulting calculation and the account's manabar recharge intervals (account.get_manabar_recharge_timedelta).
|
|
656
|
+
Values are stored as integer percentage units where HIVE_100_PERCENT (typically 10000) represents 100.00%.
|
|
657
|
+
|
|
658
|
+
Side effects:
|
|
659
|
+
- Modifies self.vp_timestamp, self.vp, self.downvote_vp_timestamp, and self.downvote_vp in place.
|
|
660
|
+
"""
|
|
562
661
|
self.vp_timestamp = [self.timestamps[1]]
|
|
563
|
-
self.vp = [
|
|
662
|
+
self.vp = [HIVE_100_PERCENT]
|
|
564
663
|
HF_21 = datetime(2019, 8, 27, 15, tzinfo=timezone.utc)
|
|
565
664
|
if self.timestamps[1] > HF_21:
|
|
566
665
|
self.downvote_vp_timestamp = [self.timestamps[1]]
|
|
567
666
|
else:
|
|
568
667
|
self.downvote_vp_timestamp = [HF_21]
|
|
569
|
-
self.downvote_vp = [
|
|
668
|
+
self.downvote_vp = [HIVE_100_PERCENT]
|
|
570
669
|
|
|
571
670
|
for ts, weight in zip(self.out_vote_timestamp, self.out_vote_weight):
|
|
572
671
|
regenerated_vp = 0
|
|
573
672
|
if ts > HF_21 and weight < 0:
|
|
574
673
|
self.downvote_vp.append(self.downvote_vp[-1])
|
|
575
|
-
if self.downvote_vp[-1] <
|
|
674
|
+
if self.downvote_vp[-1] < HIVE_100_PERCENT:
|
|
576
675
|
regenerated_vp = (
|
|
577
676
|
((ts - self.downvote_vp_timestamp[-1]).total_seconds())
|
|
578
|
-
*
|
|
579
|
-
/
|
|
677
|
+
* HIVE_100_PERCENT
|
|
678
|
+
/ HIVE_VOTE_REGENERATION_SECONDS
|
|
580
679
|
)
|
|
581
680
|
self.downvote_vp[-1] += int(regenerated_vp)
|
|
582
681
|
|
|
583
|
-
if self.downvote_vp[-1] >
|
|
584
|
-
self.downvote_vp[-1] =
|
|
682
|
+
if self.downvote_vp[-1] > HIVE_100_PERCENT:
|
|
683
|
+
self.downvote_vp[-1] = HIVE_100_PERCENT
|
|
585
684
|
recharge_time = self.account.get_manabar_recharge_timedelta(
|
|
586
685
|
{"current_mana_pct": self.downvote_vp[-2] / 100}
|
|
587
686
|
)
|
|
@@ -589,44 +688,44 @@ class AccountSnapshot(list):
|
|
|
589
688
|
self.downvote_vp_timestamp.append(
|
|
590
689
|
self.downvote_vp_timestamp[-1] + recharge_time
|
|
591
690
|
)
|
|
592
|
-
self.downvote_vp.append(
|
|
691
|
+
self.downvote_vp.append(HIVE_100_PERCENT)
|
|
593
692
|
|
|
594
693
|
# Add charged downvote VP just before new Vote
|
|
595
694
|
self.downvote_vp_timestamp.append(ts - timedelta(seconds=1))
|
|
596
695
|
self.downvote_vp.append(
|
|
597
|
-
min([
|
|
696
|
+
min([HIVE_100_PERCENT, self.downvote_vp[-1] + regenerated_vp])
|
|
598
697
|
)
|
|
599
698
|
|
|
600
699
|
self.downvote_vp[-1] -= (
|
|
601
|
-
self.blockchain._calc_resulting_vote(
|
|
700
|
+
self.blockchain._calc_resulting_vote(HIVE_100_PERCENT, weight) * 4
|
|
602
701
|
)
|
|
603
702
|
# Downvote mana pool is 1/4th of the upvote mana pool, so it gets drained 4 times as quick
|
|
604
703
|
if self.downvote_vp[-1] < 0:
|
|
605
704
|
# There's most likely a better solution to this that what I did here
|
|
606
705
|
self.vp.append(self.vp[-1])
|
|
607
706
|
|
|
608
|
-
if self.vp[-1] <
|
|
707
|
+
if self.vp[-1] < HIVE_100_PERCENT:
|
|
609
708
|
regenerated_vp = (
|
|
610
709
|
((ts - self.vp_timestamp[-1]).total_seconds())
|
|
611
|
-
*
|
|
612
|
-
/
|
|
710
|
+
* HIVE_100_PERCENT
|
|
711
|
+
/ HIVE_VOTE_REGENERATION_SECONDS
|
|
613
712
|
)
|
|
614
713
|
self.vp[-1] += int(regenerated_vp)
|
|
615
714
|
|
|
616
|
-
if self.vp[-1] >
|
|
617
|
-
self.vp[-1] =
|
|
715
|
+
if self.vp[-1] > HIVE_100_PERCENT:
|
|
716
|
+
self.vp[-1] = HIVE_100_PERCENT
|
|
618
717
|
recharge_time = self.account.get_manabar_recharge_timedelta(
|
|
619
718
|
{"current_mana_pct": self.vp[-2] / 100}
|
|
620
719
|
)
|
|
621
720
|
# Add full VP once fully charged
|
|
622
721
|
self.vp_timestamp.append(self.vp_timestamp[-1] + recharge_time)
|
|
623
|
-
self.vp.append(
|
|
624
|
-
if self.vp[-1] ==
|
|
722
|
+
self.vp.append(HIVE_100_PERCENT)
|
|
723
|
+
if self.vp[-1] == HIVE_100_PERCENT and ts - self.vp_timestamp[-1] > timedelta(
|
|
625
724
|
seconds=1
|
|
626
725
|
):
|
|
627
726
|
# Add charged VP just before new Vote
|
|
628
727
|
self.vp_timestamp.append(ts - timedelta(seconds=1))
|
|
629
|
-
self.vp.append(min([
|
|
728
|
+
self.vp.append(min([HIVE_100_PERCENT, self.vp[-1] + regenerated_vp]))
|
|
630
729
|
self.vp[-1] += self.downvote_vp[-1] / 4
|
|
631
730
|
if self.vp[-1] < 0:
|
|
632
731
|
self.vp[-1] = 0
|
|
@@ -638,28 +737,28 @@ class AccountSnapshot(list):
|
|
|
638
737
|
else:
|
|
639
738
|
self.vp.append(self.vp[-1])
|
|
640
739
|
|
|
641
|
-
if self.vp[-1] <
|
|
740
|
+
if self.vp[-1] < HIVE_100_PERCENT:
|
|
642
741
|
regenerated_vp = (
|
|
643
742
|
((ts - self.vp_timestamp[-1]).total_seconds())
|
|
644
|
-
*
|
|
645
|
-
/
|
|
743
|
+
* HIVE_100_PERCENT
|
|
744
|
+
/ HIVE_VOTE_REGENERATION_SECONDS
|
|
646
745
|
)
|
|
647
746
|
self.vp[-1] += int(regenerated_vp)
|
|
648
747
|
|
|
649
|
-
if self.vp[-1] >
|
|
650
|
-
self.vp[-1] =
|
|
748
|
+
if self.vp[-1] > HIVE_100_PERCENT:
|
|
749
|
+
self.vp[-1] = HIVE_100_PERCENT
|
|
651
750
|
recharge_time = self.account.get_manabar_recharge_timedelta(
|
|
652
751
|
{"current_mana_pct": self.vp[-2] / 100}
|
|
653
752
|
)
|
|
654
753
|
# Add full VP once fully charged
|
|
655
754
|
self.vp_timestamp.append(self.vp_timestamp[-1] + recharge_time)
|
|
656
|
-
self.vp.append(
|
|
657
|
-
if self.vp[-1] ==
|
|
755
|
+
self.vp.append(HIVE_100_PERCENT)
|
|
756
|
+
if self.vp[-1] == HIVE_100_PERCENT and ts - self.vp_timestamp[-1] > timedelta(
|
|
658
757
|
seconds=1
|
|
659
758
|
):
|
|
660
759
|
# Add charged VP just before new Vote
|
|
661
760
|
self.vp_timestamp.append(ts - timedelta(seconds=1))
|
|
662
|
-
self.vp.append(min([
|
|
761
|
+
self.vp.append(min([HIVE_100_PERCENT, self.vp[-1] + regenerated_vp]))
|
|
663
762
|
self.vp[-1] -= self.blockchain._calc_resulting_vote(self.vp[-1], weight)
|
|
664
763
|
if self.vp[-1] < 0:
|
|
665
764
|
self.vp[-1] = 0
|
|
@@ -686,9 +785,37 @@ class AccountSnapshot(list):
|
|
|
686
785
|
self.vp_timestamp.append(datetime.now(timezone.utc))
|
|
687
786
|
|
|
688
787
|
def build_curation_arrays(self, end_date=None, sum_days=7):
|
|
689
|
-
"""
|
|
690
|
-
|
|
691
|
-
self.
|
|
788
|
+
"""
|
|
789
|
+
Compute curation-per-1000-HP time series and store them in
|
|
790
|
+
self.curation_per_1000_HP_timestamp and self.curation_per_1000_HP.
|
|
791
|
+
|
|
792
|
+
The method walks through recorded reward timestamps and curation rewards, converts
|
|
793
|
+
each curation reward (vests) to HP using the blockchain conversion, and divides
|
|
794
|
+
that reward by the effective stake (sp_eff) at the reward time to produce a
|
|
795
|
+
"curation per 1000 HP" value. Values are aggregated into contiguous windows of
|
|
796
|
+
length `sum_days`. Each window's aggregate is appended to
|
|
797
|
+
self.curation_per_1000_HP with the corresponding window end timestamp in
|
|
798
|
+
self.curation_per_1000_HP_timestamp.
|
|
799
|
+
|
|
800
|
+
Parameters:
|
|
801
|
+
end_date (datetime.datetime | None): End-boundary for the first aggregation
|
|
802
|
+
window. If None, it is set to the last reward timestamp minus the total
|
|
803
|
+
span of full `sum_days` windows that fit into the reward history.
|
|
804
|
+
sum_days (int): Window length in days for aggregation. Must be > 0.
|
|
805
|
+
|
|
806
|
+
Raises:
|
|
807
|
+
ValueError: If sum_days <= 0.
|
|
808
|
+
|
|
809
|
+
Notes:
|
|
810
|
+
- Uses self.blockchain.vests_to_hp(vests, timestamp=ts) to convert vests to HP.
|
|
811
|
+
- Uses self.get_data(timestamp=ts, index=index) to obtain the effective stake
|
|
812
|
+
(`sp_eff`) and to advance a cached index for efficient lookups.
|
|
813
|
+
- The per-window aggregation normalizes values to a "per 1000 HP" basis and
|
|
814
|
+
scales them by (7 / sum_days) so the resulting numbers are comparable to a
|
|
815
|
+
7-day baseline.
|
|
816
|
+
"""
|
|
817
|
+
self.curation_per_1000_HP_timestamp = []
|
|
818
|
+
self.curation_per_1000_HP = []
|
|
692
819
|
if sum_days <= 0:
|
|
693
820
|
raise ValueError("sum_days must be greater than 0")
|
|
694
821
|
index = 0
|
|
@@ -699,12 +826,7 @@ class AccountSnapshot(list):
|
|
|
699
826
|
for ts, vests in zip(self.reward_timestamps, self.curation_rewards):
|
|
700
827
|
if vests == 0:
|
|
701
828
|
continue
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
if isinstance(self.blockchain, Steem):
|
|
705
|
-
sp = self.blockchain.vests_to_sp(vests, timestamp=ts)
|
|
706
|
-
else:
|
|
707
|
-
sp = self.blockchain.vests_to_hp(vests, timestamp=ts)
|
|
829
|
+
sp = self.blockchain.vests_to_hp(vests, timestamp=ts)
|
|
708
830
|
data = self.get_data(timestamp=ts, index=index)
|
|
709
831
|
index = data["index"]
|
|
710
832
|
if "sp_eff" in data and data["sp_eff"] > 0:
|
|
@@ -714,8 +836,8 @@ class AccountSnapshot(list):
|
|
|
714
836
|
if ts < end_date:
|
|
715
837
|
curation_sum += curation_1k_sp
|
|
716
838
|
else:
|
|
717
|
-
self.
|
|
718
|
-
self.
|
|
839
|
+
self.curation_per_1000_HP_timestamp.append(end_date)
|
|
840
|
+
self.curation_per_1000_HP.append(curation_sum)
|
|
719
841
|
end_date = end_date + timedelta(days=sum_days)
|
|
720
842
|
curation_sum = 0
|
|
721
843
|
|