hive-nectar 0.0.2__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.2.dist-info/METADATA +182 -0
- hive_nectar-0.0.2.dist-info/RECORD +86 -0
- hive_nectar-0.0.2.dist-info/WHEEL +4 -0
- hive_nectar-0.0.2.dist-info/entry_points.txt +2 -0
- hive_nectar-0.0.2.dist-info/licenses/LICENSE.txt +23 -0
- nectar/__init__.py +32 -0
- nectar/account.py +4371 -0
- nectar/amount.py +475 -0
- nectar/asciichart.py +270 -0
- nectar/asset.py +82 -0
- nectar/block.py +446 -0
- nectar/blockchain.py +1178 -0
- nectar/blockchaininstance.py +2284 -0
- nectar/blockchainobject.py +221 -0
- nectar/blurt.py +563 -0
- nectar/cli.py +6285 -0
- nectar/comment.py +1217 -0
- nectar/community.py +513 -0
- nectar/constants.py +111 -0
- nectar/conveyor.py +309 -0
- nectar/discussions.py +1709 -0
- nectar/exceptions.py +149 -0
- nectar/hive.py +546 -0
- nectar/hivesigner.py +420 -0
- nectar/imageuploader.py +72 -0
- nectar/instance.py +129 -0
- nectar/market.py +1013 -0
- nectar/memo.py +449 -0
- nectar/message.py +357 -0
- nectar/nodelist.py +444 -0
- nectar/price.py +557 -0
- nectar/profile.py +65 -0
- nectar/rc.py +308 -0
- nectar/snapshot.py +726 -0
- nectar/steem.py +582 -0
- nectar/storage.py +53 -0
- nectar/transactionbuilder.py +622 -0
- nectar/utils.py +545 -0
- nectar/version.py +2 -0
- nectar/vote.py +557 -0
- nectar/wallet.py +472 -0
- nectar/witness.py +617 -0
- nectarapi/__init__.py +11 -0
- nectarapi/exceptions.py +123 -0
- nectarapi/graphenerpc.py +589 -0
- nectarapi/node.py +178 -0
- nectarapi/noderpc.py +229 -0
- nectarapi/rpcutils.py +97 -0
- nectarapi/version.py +2 -0
- nectarbase/__init__.py +14 -0
- nectarbase/ledgertransactions.py +75 -0
- nectarbase/memo.py +243 -0
- nectarbase/objects.py +429 -0
- nectarbase/objecttypes.py +22 -0
- nectarbase/operationids.py +102 -0
- nectarbase/operations.py +1297 -0
- nectarbase/signedtransactions.py +48 -0
- nectarbase/transactions.py +11 -0
- nectarbase/version.py +2 -0
- nectargrapheneapi/__init__.py +6 -0
- nectargraphenebase/__init__.py +27 -0
- nectargraphenebase/account.py +846 -0
- nectargraphenebase/aes.py +52 -0
- nectargraphenebase/base58.py +192 -0
- nectargraphenebase/bip32.py +494 -0
- nectargraphenebase/bip38.py +134 -0
- nectargraphenebase/chains.py +149 -0
- nectargraphenebase/dictionary.py +3 -0
- nectargraphenebase/ecdsasig.py +326 -0
- nectargraphenebase/objects.py +123 -0
- nectargraphenebase/objecttypes.py +6 -0
- nectargraphenebase/operationids.py +3 -0
- nectargraphenebase/operations.py +23 -0
- nectargraphenebase/prefix.py +11 -0
- nectargraphenebase/py23.py +38 -0
- nectargraphenebase/signedtransactions.py +201 -0
- nectargraphenebase/types.py +419 -0
- nectargraphenebase/unsignedtransactions.py +283 -0
- nectargraphenebase/version.py +2 -0
- nectarstorage/__init__.py +38 -0
- nectarstorage/base.py +306 -0
- nectarstorage/exceptions.py +16 -0
- nectarstorage/interfaces.py +237 -0
- nectarstorage/masterpassword.py +239 -0
- nectarstorage/ram.py +30 -0
- nectarstorage/sqlite.py +334 -0
nectar/witness.py
ADDED
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
import json
|
|
3
|
+
from datetime import date, datetime, timezone
|
|
4
|
+
|
|
5
|
+
from prettytable import PrettyTable
|
|
6
|
+
|
|
7
|
+
from nectarbase import operations
|
|
8
|
+
|
|
9
|
+
from .account import Account
|
|
10
|
+
from .amount import Amount
|
|
11
|
+
from .blockchainobject import BlockchainObject
|
|
12
|
+
from .exceptions import WitnessDoesNotExistsException
|
|
13
|
+
from .instance import shared_blockchain_instance
|
|
14
|
+
from .utils import formatTimeString
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class Witness(BlockchainObject):
|
|
18
|
+
"""Read data about a witness in the chain
|
|
19
|
+
|
|
20
|
+
:param str owner: Name of the witness
|
|
21
|
+
:param bool lazy: Use lazy loading
|
|
22
|
+
:param bool full: Get full data about witness
|
|
23
|
+
:param nectar.nectar.nectar blockchain_instance: nectar
|
|
24
|
+
instance to use when accesing a RPC
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
type_id = 3
|
|
28
|
+
|
|
29
|
+
def __init__(self, owner, full=False, lazy=False, blockchain_instance=None, **kwargs):
|
|
30
|
+
self.full = full
|
|
31
|
+
self.lazy = lazy
|
|
32
|
+
if blockchain_instance is None:
|
|
33
|
+
if kwargs.get("steem_instance"):
|
|
34
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
35
|
+
elif kwargs.get("hive_instance"):
|
|
36
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
37
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
38
|
+
if isinstance(owner, dict):
|
|
39
|
+
owner = self._parse_json_data(owner)
|
|
40
|
+
super(Witness, self).__init__(
|
|
41
|
+
owner, lazy=lazy, full=full, id_item="owner", blockchain_instance=blockchain_instance
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
def refresh(self):
|
|
45
|
+
if not self.identifier:
|
|
46
|
+
return
|
|
47
|
+
if not self.blockchain.is_connected():
|
|
48
|
+
return
|
|
49
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
50
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
51
|
+
witness = self.blockchain.rpc.find_witnesses(
|
|
52
|
+
{"owners": [self.identifier]}, api="database"
|
|
53
|
+
)["witnesses"]
|
|
54
|
+
if len(witness) > 0:
|
|
55
|
+
witness = witness[0]
|
|
56
|
+
else:
|
|
57
|
+
witness = self.blockchain.rpc.get_witness_by_account(self.identifier)
|
|
58
|
+
if not witness:
|
|
59
|
+
raise WitnessDoesNotExistsException(self.identifier)
|
|
60
|
+
witness = self._parse_json_data(witness)
|
|
61
|
+
super(Witness, self).__init__(
|
|
62
|
+
witness,
|
|
63
|
+
id_item="owner",
|
|
64
|
+
lazy=self.lazy,
|
|
65
|
+
full=self.full,
|
|
66
|
+
blockchain_instance=self.blockchain,
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
def _parse_json_data(self, witness):
|
|
70
|
+
parse_times = [
|
|
71
|
+
"created",
|
|
72
|
+
"last_sbd_exchange_update",
|
|
73
|
+
"hardfork_time_vote",
|
|
74
|
+
"last_hbd_exchange_update",
|
|
75
|
+
]
|
|
76
|
+
for p in parse_times:
|
|
77
|
+
if p in witness and isinstance(witness.get(p), str):
|
|
78
|
+
witness[p] = formatTimeString(witness.get(p, "1970-01-01T00:00:00"))
|
|
79
|
+
parse_int = [
|
|
80
|
+
"votes",
|
|
81
|
+
"virtual_last_update",
|
|
82
|
+
"virtual_position",
|
|
83
|
+
"virtual_scheduled_time",
|
|
84
|
+
]
|
|
85
|
+
for p in parse_int:
|
|
86
|
+
if p in witness and isinstance(witness.get(p), str):
|
|
87
|
+
witness[p] = int(witness.get(p, "0"))
|
|
88
|
+
return witness
|
|
89
|
+
|
|
90
|
+
def json(self):
|
|
91
|
+
output = self.copy()
|
|
92
|
+
parse_times = [
|
|
93
|
+
"created",
|
|
94
|
+
"last_sbd_exchange_update",
|
|
95
|
+
"hardfork_time_vote",
|
|
96
|
+
"last_hbd_exchange_update",
|
|
97
|
+
]
|
|
98
|
+
for p in parse_times:
|
|
99
|
+
if p in output:
|
|
100
|
+
p_date = output.get(p, datetime(1970, 1, 1, 0, 0))
|
|
101
|
+
if isinstance(p_date, (datetime, date)):
|
|
102
|
+
output[p] = formatTimeString(p_date)
|
|
103
|
+
else:
|
|
104
|
+
output[p] = p_date
|
|
105
|
+
parse_int = [
|
|
106
|
+
"votes",
|
|
107
|
+
"virtual_last_update",
|
|
108
|
+
"virtual_position",
|
|
109
|
+
"virtual_scheduled_time",
|
|
110
|
+
]
|
|
111
|
+
for p in parse_int:
|
|
112
|
+
if p in output and isinstance(output[p], int):
|
|
113
|
+
output[p] = str(output[p])
|
|
114
|
+
return json.loads(str(json.dumps(output)))
|
|
115
|
+
|
|
116
|
+
@property
|
|
117
|
+
def account(self):
|
|
118
|
+
return Account(self["owner"], blockchain_instance=self.blockchain)
|
|
119
|
+
|
|
120
|
+
@property
|
|
121
|
+
def is_active(self):
|
|
122
|
+
return (
|
|
123
|
+
len(self["signing_key"]) > 3
|
|
124
|
+
and self["signing_key"][3:] != "1111111111111111111111111111111114T1Anm"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
def feed_publish(self, base, quote=None, account=None):
|
|
128
|
+
"""Publish a feed price as a witness.
|
|
129
|
+
|
|
130
|
+
:param float base: USD Price of STEEM in SBD (implied price)
|
|
131
|
+
:param float quote: (optional) Quote Price. Should be 1.000 (default), unless
|
|
132
|
+
we are adjusting the feed to support the peg.
|
|
133
|
+
:param str account: (optional) the source account for the transfer
|
|
134
|
+
if not self["owner"]
|
|
135
|
+
"""
|
|
136
|
+
quote = quote if quote is not None else "1.000 %s" % (self.blockchain.token_symbol)
|
|
137
|
+
if not account:
|
|
138
|
+
account = self["owner"]
|
|
139
|
+
if not account:
|
|
140
|
+
raise ValueError("You need to provide an account")
|
|
141
|
+
|
|
142
|
+
account = Account(account, blockchain_instance=self.blockchain)
|
|
143
|
+
if isinstance(base, Amount):
|
|
144
|
+
base = Amount(base, blockchain_instance=self.blockchain)
|
|
145
|
+
elif isinstance(base, str):
|
|
146
|
+
base = Amount(base, blockchain_instance=self.blockchain)
|
|
147
|
+
else:
|
|
148
|
+
base = Amount(
|
|
149
|
+
base, self.blockchain.backed_token_symbol, blockchain_instance=self.blockchain
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
if isinstance(quote, Amount):
|
|
153
|
+
quote = Amount(quote, blockchain_instance=self.blockchain)
|
|
154
|
+
elif isinstance(quote, str):
|
|
155
|
+
quote = Amount(quote, blockchain_instance=self.blockchain)
|
|
156
|
+
else:
|
|
157
|
+
quote = Amount(quote, self.blockchain.token_symbol, blockchain_instance=self.blockchain)
|
|
158
|
+
|
|
159
|
+
if not base.symbol == self.blockchain.backed_token_symbol:
|
|
160
|
+
raise AssertionError()
|
|
161
|
+
if not quote.symbol == self.blockchain.token_symbol:
|
|
162
|
+
raise AssertionError()
|
|
163
|
+
op = operations.Feed_publish(
|
|
164
|
+
**{
|
|
165
|
+
"publisher": account["name"],
|
|
166
|
+
"exchange_rate": {
|
|
167
|
+
"base": base,
|
|
168
|
+
"quote": quote,
|
|
169
|
+
},
|
|
170
|
+
"prefix": self.blockchain.prefix,
|
|
171
|
+
"json_str": not bool(self.blockchain.config["use_condenser"]),
|
|
172
|
+
}
|
|
173
|
+
)
|
|
174
|
+
return self.blockchain.finalizeOp(op, account, "active")
|
|
175
|
+
|
|
176
|
+
def update(self, signing_key, url, props, account=None):
|
|
177
|
+
"""Update witness
|
|
178
|
+
|
|
179
|
+
:param str signing_key: Signing key
|
|
180
|
+
:param str url: URL
|
|
181
|
+
:param dict props: Properties
|
|
182
|
+
:param str account: (optional) witness account name
|
|
183
|
+
|
|
184
|
+
Properties:::
|
|
185
|
+
|
|
186
|
+
{
|
|
187
|
+
"account_creation_fee": x,
|
|
188
|
+
"maximum_block_size": x,
|
|
189
|
+
"sbd_interest_rate": x,
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
"""
|
|
193
|
+
if not account:
|
|
194
|
+
account = self["owner"]
|
|
195
|
+
return self.blockchain.witness_update(signing_key, url, props, account=account)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
class WitnessesObject(list):
|
|
199
|
+
def printAsTable(self, sort_key="votes", reverse=True, return_str=False, **kwargs):
|
|
200
|
+
no_feed = False
|
|
201
|
+
if (
|
|
202
|
+
len(self) > 0
|
|
203
|
+
and "sbd_exchange_rate" not in self[0]
|
|
204
|
+
and "hbd_exchange_rate" not in self[0]
|
|
205
|
+
):
|
|
206
|
+
table_header = ["Name", "Votes [PV]", "Disabled", "Missed", "Fee", "Size", "Version"]
|
|
207
|
+
no_feed = True
|
|
208
|
+
else:
|
|
209
|
+
table_header = [
|
|
210
|
+
"Name",
|
|
211
|
+
"Votes [PV]",
|
|
212
|
+
"Disabled",
|
|
213
|
+
"Missed",
|
|
214
|
+
"Feed base",
|
|
215
|
+
"Feed quote",
|
|
216
|
+
"Feed update",
|
|
217
|
+
"Fee",
|
|
218
|
+
"Size",
|
|
219
|
+
"Interest",
|
|
220
|
+
"Version",
|
|
221
|
+
]
|
|
222
|
+
if "sbd_exchange_rate" in self[0]:
|
|
223
|
+
bd_exchange_rate = "sbd_exchange_rate"
|
|
224
|
+
bd_interest_rate = "sbd_interest_rate"
|
|
225
|
+
last_bd_exchange_update = "last_sbd_exchange_update"
|
|
226
|
+
else:
|
|
227
|
+
bd_exchange_rate = "hbd_exchange_rate"
|
|
228
|
+
bd_interest_rate = "hbd_interest_rate"
|
|
229
|
+
last_bd_exchange_update = "last_hbd_exchange_update"
|
|
230
|
+
t = PrettyTable(table_header)
|
|
231
|
+
t.align = "l"
|
|
232
|
+
if sort_key == "base":
|
|
233
|
+
sortedList = sorted(
|
|
234
|
+
self, key=lambda self: self[bd_exchange_rate]["base"], reverse=reverse
|
|
235
|
+
)
|
|
236
|
+
elif sort_key == "quote":
|
|
237
|
+
sortedList = sorted(
|
|
238
|
+
self, key=lambda self: self[bd_exchange_rate]["quote"], reverse=reverse
|
|
239
|
+
)
|
|
240
|
+
elif sort_key == "last_sbd_exchange_update" or sort_key == "last_hbd_exchange_update":
|
|
241
|
+
sortedList = sorted(
|
|
242
|
+
self,
|
|
243
|
+
key=lambda self: (
|
|
244
|
+
datetime.now(timezone.utc) - self[last_bd_exchange_update]
|
|
245
|
+
).total_seconds(),
|
|
246
|
+
reverse=reverse,
|
|
247
|
+
)
|
|
248
|
+
elif sort_key == "account_creation_fee":
|
|
249
|
+
sortedList = sorted(
|
|
250
|
+
self, key=lambda self: self["props"]["account_creation_fee"], reverse=reverse
|
|
251
|
+
)
|
|
252
|
+
elif sort_key == "sbd_interest_rate" or sort_key == "hbd_interest_rate":
|
|
253
|
+
sortedList = sorted(
|
|
254
|
+
self, key=lambda self: self["props"][bd_interest_rate], reverse=reverse
|
|
255
|
+
)
|
|
256
|
+
elif sort_key == "maximum_block_size":
|
|
257
|
+
sortedList = sorted(
|
|
258
|
+
self, key=lambda self: self["props"]["maximum_block_size"], reverse=reverse
|
|
259
|
+
)
|
|
260
|
+
elif sort_key == "votes":
|
|
261
|
+
sortedList = sorted(self, key=lambda self: int(self[sort_key]), reverse=reverse)
|
|
262
|
+
else:
|
|
263
|
+
sortedList = sorted(self, key=lambda self: self[sort_key], reverse=reverse)
|
|
264
|
+
for witness in sortedList:
|
|
265
|
+
disabled = ""
|
|
266
|
+
if not witness.is_active:
|
|
267
|
+
disabled = "yes"
|
|
268
|
+
|
|
269
|
+
if no_feed:
|
|
270
|
+
t.add_row(
|
|
271
|
+
[
|
|
272
|
+
witness["owner"],
|
|
273
|
+
str(round(int(witness["votes"]) / 1e15, 2)),
|
|
274
|
+
disabled,
|
|
275
|
+
str(witness["total_missed"]),
|
|
276
|
+
str(witness["props"]["account_creation_fee"]),
|
|
277
|
+
str(witness["props"]["maximum_block_size"]),
|
|
278
|
+
witness["running_version"],
|
|
279
|
+
]
|
|
280
|
+
)
|
|
281
|
+
else:
|
|
282
|
+
td = datetime.now(timezone.utc) - witness[last_bd_exchange_update]
|
|
283
|
+
t.add_row(
|
|
284
|
+
[
|
|
285
|
+
witness["owner"],
|
|
286
|
+
str(round(int(witness["votes"]) / 1e15, 2)),
|
|
287
|
+
disabled,
|
|
288
|
+
str(witness["total_missed"]),
|
|
289
|
+
str(
|
|
290
|
+
Amount(
|
|
291
|
+
witness[bd_exchange_rate]["base"],
|
|
292
|
+
blockchain_instance=self.blockchain,
|
|
293
|
+
)
|
|
294
|
+
),
|
|
295
|
+
str(
|
|
296
|
+
Amount(
|
|
297
|
+
witness[bd_exchange_rate]["quote"],
|
|
298
|
+
blockchain_instance=self.blockchain,
|
|
299
|
+
)
|
|
300
|
+
),
|
|
301
|
+
str(td.days)
|
|
302
|
+
+ " days "
|
|
303
|
+
+ str(td.seconds // 3600)
|
|
304
|
+
+ ":"
|
|
305
|
+
+ str((td.seconds // 60) % 60),
|
|
306
|
+
str(
|
|
307
|
+
Amount(
|
|
308
|
+
witness["props"]["account_creation_fee"],
|
|
309
|
+
blockchain_instance=self.blockchain,
|
|
310
|
+
)
|
|
311
|
+
),
|
|
312
|
+
str(witness["props"]["maximum_block_size"]),
|
|
313
|
+
str(witness["props"][bd_interest_rate] / 100) + " %",
|
|
314
|
+
witness["running_version"],
|
|
315
|
+
]
|
|
316
|
+
)
|
|
317
|
+
if return_str:
|
|
318
|
+
return t.get_string(**kwargs)
|
|
319
|
+
else:
|
|
320
|
+
print(t.get_string(**kwargs))
|
|
321
|
+
|
|
322
|
+
def get_votes_sum(self):
|
|
323
|
+
vote_sum = 0
|
|
324
|
+
for witness in self:
|
|
325
|
+
vote_sum += int(witness["votes"])
|
|
326
|
+
return vote_sum
|
|
327
|
+
|
|
328
|
+
def __contains__(self, item):
|
|
329
|
+
from .account import Account
|
|
330
|
+
|
|
331
|
+
if isinstance(item, Account):
|
|
332
|
+
name = item["name"]
|
|
333
|
+
elif self.blockchain:
|
|
334
|
+
account = Account(item, blockchain_instance=self.blockchain)
|
|
335
|
+
name = account["name"]
|
|
336
|
+
|
|
337
|
+
return any([name == x["owner"] for x in self])
|
|
338
|
+
|
|
339
|
+
def __str__(self):
|
|
340
|
+
return self.printAsTable(return_str=True)
|
|
341
|
+
|
|
342
|
+
def __repr__(self):
|
|
343
|
+
return "<%s %s>" % (self.__class__.__name__, str(self.identifier))
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
class GetWitnesses(WitnessesObject):
|
|
347
|
+
"""Obtain a list of witnesses
|
|
348
|
+
|
|
349
|
+
:param list name_list: list of witneses to fetch
|
|
350
|
+
:param int batch_limit: (optional) maximum number of witnesses
|
|
351
|
+
to fetch per call, defaults to 100
|
|
352
|
+
:param Steem steem_instance: Steem() instance to use when
|
|
353
|
+
accessing a RPCcreator = Witness(creator, steem_instance=self)
|
|
354
|
+
|
|
355
|
+
.. code-block:: python
|
|
356
|
+
|
|
357
|
+
from nectar.witness import GetWitnesses
|
|
358
|
+
w = GetWitnesses(["gtg", "jesta"])
|
|
359
|
+
print(w[0].json())
|
|
360
|
+
print(w[1].json())
|
|
361
|
+
|
|
362
|
+
"""
|
|
363
|
+
|
|
364
|
+
def __init__(
|
|
365
|
+
self, name_list, batch_limit=100, lazy=False, full=True, blockchain_instance=None, **kwargs
|
|
366
|
+
):
|
|
367
|
+
if blockchain_instance is None:
|
|
368
|
+
if kwargs.get("steem_instance"):
|
|
369
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
370
|
+
elif kwargs.get("hive_instance"):
|
|
371
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
372
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
373
|
+
if not self.blockchain.is_connected():
|
|
374
|
+
return
|
|
375
|
+
witnesses = []
|
|
376
|
+
name_cnt = 0
|
|
377
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
378
|
+
while name_cnt < len(name_list):
|
|
379
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
380
|
+
witnesses += self.blockchain.rpc.find_witnesses(
|
|
381
|
+
{"owners": name_list[name_cnt : batch_limit + name_cnt]}, api="database"
|
|
382
|
+
)["witnesses"]
|
|
383
|
+
name_cnt += batch_limit
|
|
384
|
+
else:
|
|
385
|
+
for witness in name_list:
|
|
386
|
+
witnesses.append(self.blockchain.rpc.get_witness_by_account(witness))
|
|
387
|
+
self.identifier = ""
|
|
388
|
+
super(GetWitnesses, self).__init__(
|
|
389
|
+
[
|
|
390
|
+
Witness(x, lazy=lazy, full=full, blockchain_instance=self.blockchain)
|
|
391
|
+
for x in witnesses
|
|
392
|
+
]
|
|
393
|
+
)
|
|
394
|
+
|
|
395
|
+
|
|
396
|
+
class Witnesses(WitnessesObject):
|
|
397
|
+
"""Obtain a list of **active** witnesses and the current schedule
|
|
398
|
+
|
|
399
|
+
:param Steem steem_instance: Steem instance to use when
|
|
400
|
+
accesing a RPC
|
|
401
|
+
|
|
402
|
+
.. code-block:: python
|
|
403
|
+
|
|
404
|
+
>>> from nectar.witness import Witnesses
|
|
405
|
+
>>> Witnesses()
|
|
406
|
+
<Witnesses >
|
|
407
|
+
|
|
408
|
+
"""
|
|
409
|
+
|
|
410
|
+
def __init__(self, lazy=False, full=True, blockchain_instance=None, **kwargs):
|
|
411
|
+
if blockchain_instance is None:
|
|
412
|
+
if kwargs.get("steem_instance"):
|
|
413
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
414
|
+
elif kwargs.get("hive_instance"):
|
|
415
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
416
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
417
|
+
self.lazy = lazy
|
|
418
|
+
self.full = full
|
|
419
|
+
self.refresh()
|
|
420
|
+
|
|
421
|
+
def refresh(self):
|
|
422
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
423
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
424
|
+
self.active_witnessess = self.blockchain.rpc.get_active_witnesses(api="database")[
|
|
425
|
+
"witnesses"
|
|
426
|
+
]
|
|
427
|
+
self.schedule = self.blockchain.rpc.get_witness_schedule(api="database")
|
|
428
|
+
if self.blockchain.config["use_condenser"]:
|
|
429
|
+
self.witness_count = self.blockchain.rpc.get_witness_count(api="condenser")
|
|
430
|
+
else:
|
|
431
|
+
self.witness_count = self.blockchain.rpc.get_witness_count()
|
|
432
|
+
else:
|
|
433
|
+
self.active_witnessess = self.blockchain.rpc.get_active_witnesses()
|
|
434
|
+
self.schedule = self.blockchain.rpc.get_witness_schedule()
|
|
435
|
+
self.witness_count = self.blockchain.rpc.get_witness_count()
|
|
436
|
+
self.current_witness = self.blockchain.get_dynamic_global_properties(use_stored_data=False)[
|
|
437
|
+
"current_witness"
|
|
438
|
+
]
|
|
439
|
+
self.identifier = ""
|
|
440
|
+
super(Witnesses, self).__init__(
|
|
441
|
+
[
|
|
442
|
+
Witness(x, lazy=self.lazy, full=self.full, blockchain_instance=self.blockchain)
|
|
443
|
+
for x in self.active_witnessess
|
|
444
|
+
]
|
|
445
|
+
)
|
|
446
|
+
|
|
447
|
+
|
|
448
|
+
class WitnessesVotedByAccount(WitnessesObject):
|
|
449
|
+
"""Obtain a list of witnesses which have been voted by an account
|
|
450
|
+
|
|
451
|
+
:param str account: Account name
|
|
452
|
+
:param Steem steem_instance: Steem instance to use when
|
|
453
|
+
accesing a RPC
|
|
454
|
+
|
|
455
|
+
.. code-block:: python
|
|
456
|
+
|
|
457
|
+
>>> from nectar.witness import WitnessesVotedByAccount
|
|
458
|
+
>>> WitnessesVotedByAccount("gtg")
|
|
459
|
+
<WitnessesVotedByAccount gtg>
|
|
460
|
+
|
|
461
|
+
"""
|
|
462
|
+
|
|
463
|
+
def __init__(self, account, lazy=False, full=True, blockchain_instance=None, **kwargs):
|
|
464
|
+
if blockchain_instance is None:
|
|
465
|
+
if kwargs.get("steem_instance"):
|
|
466
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
467
|
+
elif kwargs.get("hive_instance"):
|
|
468
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
469
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
470
|
+
self.account = Account(account, full=True, blockchain_instance=self.blockchain)
|
|
471
|
+
account_name = self.account["name"]
|
|
472
|
+
self.identifier = account_name
|
|
473
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
474
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
475
|
+
if "witnesses_voted_for" not in self.account:
|
|
476
|
+
return
|
|
477
|
+
limit = self.account["witnesses_voted_for"]
|
|
478
|
+
witnessess_dict = self.blockchain.rpc.list_witness_votes(
|
|
479
|
+
{"start": [account_name], "limit": limit, "order": "by_account_witness"},
|
|
480
|
+
api="database",
|
|
481
|
+
)["votes"]
|
|
482
|
+
witnessess = []
|
|
483
|
+
for w in witnessess_dict:
|
|
484
|
+
witnessess.append(w["witness"])
|
|
485
|
+
else:
|
|
486
|
+
if "witness_votes" not in self.account:
|
|
487
|
+
return
|
|
488
|
+
witnessess = self.account["witness_votes"]
|
|
489
|
+
|
|
490
|
+
super(WitnessesVotedByAccount, self).__init__(
|
|
491
|
+
[
|
|
492
|
+
Witness(x, lazy=lazy, full=full, blockchain_instance=self.blockchain)
|
|
493
|
+
for x in witnessess
|
|
494
|
+
]
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
class WitnessesRankedByVote(WitnessesObject):
|
|
499
|
+
"""Obtain a list of witnesses ranked by Vote
|
|
500
|
+
|
|
501
|
+
:param str from_account: Witness name from which the lists starts (default = "")
|
|
502
|
+
:param int limit: Limits the number of shown witnesses (default = 100)
|
|
503
|
+
:param Steem steem_instance: Steem instance to use when
|
|
504
|
+
accesing a RPC
|
|
505
|
+
|
|
506
|
+
.. code-block:: python
|
|
507
|
+
|
|
508
|
+
>>> from nectar.witness import WitnessesRankedByVote
|
|
509
|
+
>>> WitnessesRankedByVote(limit=100)
|
|
510
|
+
<WitnessesRankedByVote >
|
|
511
|
+
|
|
512
|
+
"""
|
|
513
|
+
|
|
514
|
+
def __init__(
|
|
515
|
+
self, from_account="", limit=100, lazy=False, full=False, blockchain_instance=None, **kwargs
|
|
516
|
+
):
|
|
517
|
+
if blockchain_instance is None:
|
|
518
|
+
if kwargs.get("steem_instance"):
|
|
519
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
520
|
+
elif kwargs.get("hive_instance"):
|
|
521
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
522
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
523
|
+
witnessList = []
|
|
524
|
+
last_limit = limit
|
|
525
|
+
self.identifier = ""
|
|
526
|
+
use_condenser = self.blockchain.config["use_condenser"]
|
|
527
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
528
|
+
if self.blockchain.rpc.get_use_appbase() and not use_condenser:
|
|
529
|
+
query_limit = 1000
|
|
530
|
+
else:
|
|
531
|
+
query_limit = 100
|
|
532
|
+
if self.blockchain.rpc.get_use_appbase() and not use_condenser and from_account == "":
|
|
533
|
+
last_account = None
|
|
534
|
+
elif self.blockchain.rpc.get_use_appbase() and not use_condenser:
|
|
535
|
+
last_account = Witness(from_account, blockchain_instance=self.blockchain)["votes"]
|
|
536
|
+
else:
|
|
537
|
+
last_account = from_account
|
|
538
|
+
if limit > query_limit:
|
|
539
|
+
while last_limit > query_limit:
|
|
540
|
+
tmpList = WitnessesRankedByVote(last_account, query_limit)
|
|
541
|
+
if last_limit < limit:
|
|
542
|
+
witnessList.extend(tmpList[1:])
|
|
543
|
+
last_limit -= query_limit - 1
|
|
544
|
+
else:
|
|
545
|
+
witnessList.extend(tmpList)
|
|
546
|
+
last_limit -= query_limit
|
|
547
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
548
|
+
last_account = witnessList[-1]["votes"]
|
|
549
|
+
else:
|
|
550
|
+
last_account = witnessList[-1]["owner"]
|
|
551
|
+
if last_limit < limit:
|
|
552
|
+
last_limit += 1
|
|
553
|
+
if self.blockchain.rpc.get_use_appbase() and not use_condenser:
|
|
554
|
+
witnessess = self.blockchain.rpc.list_witnesses(
|
|
555
|
+
{"start": [0, last_account], "limit": last_limit, "order": "by_vote_name"},
|
|
556
|
+
api="database",
|
|
557
|
+
)["witnesses"]
|
|
558
|
+
elif self.blockchain.rpc.get_use_appbase() and use_condenser:
|
|
559
|
+
witnessess = self.blockchain.rpc.get_witnesses_by_vote(
|
|
560
|
+
last_account, last_limit, api="condenser"
|
|
561
|
+
)
|
|
562
|
+
else:
|
|
563
|
+
witnessess = self.blockchain.rpc.get_witnesses_by_vote(last_account, last_limit)
|
|
564
|
+
# self.witness_count = len(self.voted_witnessess)
|
|
565
|
+
if last_limit < limit:
|
|
566
|
+
witnessess = witnessess[1:]
|
|
567
|
+
if len(witnessess) > 0:
|
|
568
|
+
for x in witnessess:
|
|
569
|
+
witnessList.append(
|
|
570
|
+
Witness(x, lazy=lazy, full=full, blockchain_instance=self.blockchain)
|
|
571
|
+
)
|
|
572
|
+
if len(witnessList) == 0:
|
|
573
|
+
return
|
|
574
|
+
super(WitnessesRankedByVote, self).__init__(witnessList)
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class ListWitnesses(WitnessesObject):
|
|
578
|
+
"""List witnesses ranked by name
|
|
579
|
+
|
|
580
|
+
:param str from_account: Witness name from which the lists starts (default = "")
|
|
581
|
+
:param int limit: Limits the number of shown witnesses (default = 100)
|
|
582
|
+
:param Steem steem_instance: Steem instance to use when
|
|
583
|
+
accesing a RPC
|
|
584
|
+
|
|
585
|
+
.. code-block:: python
|
|
586
|
+
|
|
587
|
+
>>> from nectar.witness import ListWitnesses
|
|
588
|
+
>>> ListWitnesses(from_account="gtg", limit=100)
|
|
589
|
+
<ListWitnesses gtg>
|
|
590
|
+
|
|
591
|
+
"""
|
|
592
|
+
|
|
593
|
+
def __init__(
|
|
594
|
+
self, from_account="", limit=100, lazy=False, full=False, blockchain_instance=None, **kwargs
|
|
595
|
+
):
|
|
596
|
+
if blockchain_instance is None:
|
|
597
|
+
if kwargs.get("steem_instance"):
|
|
598
|
+
blockchain_instance = kwargs["steem_instance"]
|
|
599
|
+
elif kwargs.get("hive_instance"):
|
|
600
|
+
blockchain_instance = kwargs["hive_instance"]
|
|
601
|
+
self.blockchain = blockchain_instance or shared_blockchain_instance()
|
|
602
|
+
self.identifier = from_account
|
|
603
|
+
self.blockchain.rpc.set_next_node_on_empty_reply(False)
|
|
604
|
+
if self.blockchain.rpc.get_use_appbase():
|
|
605
|
+
witnessess = self.blockchain.rpc.list_witnesses(
|
|
606
|
+
{"start": from_account, "limit": limit, "order": "by_name"}, api="database"
|
|
607
|
+
)["witnesses"]
|
|
608
|
+
else:
|
|
609
|
+
witnessess = self.blockchain.rpc.lookup_witness_accounts(from_account, limit)
|
|
610
|
+
if len(witnessess) == 0:
|
|
611
|
+
return
|
|
612
|
+
super(ListWitnesses, self).__init__(
|
|
613
|
+
[
|
|
614
|
+
Witness(x, lazy=lazy, full=full, blockchain_instance=self.blockchain)
|
|
615
|
+
for x in witnessess
|
|
616
|
+
]
|
|
617
|
+
)
|