Skip to content
Merged
2 changes: 1 addition & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@
# The short X.Y version.
version = '1.0'
# The full version, including alpha/beta/rc tags.
release = '1.0.1'
release = '1.0.2-rc1'

# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def run(self):
# Where the magic happens:
setup(
name=NAME,
version='1.0.1',
version='1.0.2-rc1',
description=DESCRIPTION,
keywords=['steem', 'steemit', 'cryptocurrency', 'blockchain'],
# long_description=long_description,
Expand Down
2 changes: 1 addition & 1 deletion steem/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# -*- coding: utf-8 -*-
from .steem import Steem

__version__ = '1.0.1'
__version__ = '1.0.2-rc1'
34 changes: 34 additions & 0 deletions steem/commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -1003,6 +1003,40 @@ def witness_update(self, signing_key, url, props, account=None):
})
return self.finalizeOp(op, account, "active")

def witness_set_properties(self, signing_key, props, account=None):
""" Update witness

:param pubkey signing_key: Signing key
:param dict props: Properties
:param str account: (optional) witness account name

Properties:::

[
["account_creation_fee": x]
["maximum_block_size": x]
["sbd_interest_rate": x]
]

"""
if not account:
account = configStorage.get("default_account")
if not account:
raise ValueError("You need to provide an account")

try:
PublicKey(signing_key)
except Exception as e:
raise e

op = operations.WitnessSetProperties(
**{
"owner": account,
"props": props,
"extensions": []
})
return self.finalizeOp(op, account, "active")

def decode_memo(self, enc_memo):
""" Try to decode an encrypted memo
"""
Expand Down
1 change: 1 addition & 0 deletions steembase/operationids.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
'claim_reward_balance',
'delegate_vesting_shares',
'account_create_with_delegation',
'witness_set_properties',
'fill_convert_request',
'author_reward',
'curation_reward',
Expand Down
59 changes: 57 additions & 2 deletions steembase/operations.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import importlib
import json
from binascii import hexlify, unhexlify
import re
import struct
from collections import OrderedDict

from steem.utils import compat_bytes
from .account import PublicKey
from .operationids import operations
from .types import (Int16, Uint16, Uint32, Uint64, String, Bytes, Array,
PointInTime, Bool, Optional, Map, Id, JsonObj,
from .types import (Int16, Uint16, Uint32, Uint64, String, HexString, Bytes,
Array, PointInTime, Bool, Optional, Map, Id, JsonObj,
StaticVariant)

default_prefix = "STM"
Expand Down Expand Up @@ -683,6 +684,60 @@ def __init__(self, *args, **kwargs):
('fee', Amount(kwargs["fee"])),
]))

class WitnessSetProperties(GrapheneObject):
"""
Based on https://github.com/holgern/beem/blob/6cc303d1b0fdfb096da78d3ff331aaa79a18ad8f/beembase/operations.py#L278-L318
"""
def __init__(self, *args, **kwargs):
if isArgsThisClass(self, args):
self.data = args[0].data
else:
if len(args) == 1 and len(kwargs) == 0:
kwargs = args[0]
prefix = kwargs.pop("prefix", default_prefix)
extensions = Array([])
props = {}
for k in kwargs["props"]:
if "key" == k[0]:
block_signing_key = (PublicKey(k[1], prefix=prefix))
props["key"] = repr(block_signing_key)
elif "new_signing_key" == k[0]:
new_signing_key = (PublicKey(k[1], prefix=prefix))
props["new_signing_key"] = repr(new_signing_key)
for k in kwargs["props"]:
if k[0] in ["key", "new_signing_key"]:
continue
if isinstance(k[1], str):
is_hex = re.match(r'^[0-9a-fA-F]+$', k[1] or '') is not None
else:
is_hex = False
if isinstance(k[1], int) and k[0] in ["account_subsidy_budget", "account_subsidy_decay", "maximum_block_size", "sbd_interest_rate"]:
props[k[0]] = (hexlify(Uint32(k[1]).__bytes__())).decode()
elif not isinstance(k[1], str) and k[0] in ["account_creation_fee"]:
props[k[0]] = (hexlify(Amount(k[1]).__bytes__())).decode()
elif not is_hex and isinstance(k[1], str) and k[0] in ["account_creation_fee"]:
props[k[0]] = (hexlify(Amount(k[1]).__bytes__())).decode()
elif not isinstance(k[1], str) and k[0] in ["sbd_exchange_rate"]:
props[k[0]] = (hexlify(ExchangeRate(k[1]).__bytes__())).decode()
elif not is_hex and k[0] in ["url"]:
props[k[0]] = (hexlify(String(k[1]).__bytes__())).decode()
else:
props[k[0]] = (k[1])
props_list = []
for k in props:
props_list.append(([String(k), HexString(props[k])]))
props_list = sorted(
props_list,
key=lambda x: str(x[0]),
reverse=False,
)
map_props = Map(props_list)

super(WitnessSetProperties, self).__init__(OrderedDict([
('owner', String(kwargs["owner"])),
('props', map_props),
('extensions', extensions),
]))

class AccountWitnessVote(GrapheneObject):
def __init__(self, *args, **kwargs):
Expand Down
14 changes: 14 additions & 0 deletions steembase/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,20 @@ def unicodify(self):
return compat_bytes("".join(r), "utf-8")


class HexString(object):
def __init__(self, d):
self.data = d

def __bytes__(self):
"""Returns bytes representation."""
d = bytes(unhexlify(compat_bytes(self.data, 'ascii')))
return varint(len(d)) + d

def __str__(self):
"""Returns data as string."""
return '%s' % str(self.data)


class Bytes:
def __init__(self, d, length=None):
self.data = d
Expand Down
20 changes: 20 additions & 0 deletions tests/block_data/witness_set_properties.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"ref_block_prefix": 82172829,
"expiration": "2018-09-24T19:22:18",
"operations": [
[
"witness_set_properties", {
"owner": "init-1",
"props": [
["account_creation_fee", "d0070000000000000354455354530000"],
["key", "032d2a4af3e23294e0a1d9dbc46e0272d8e1977ce2ae3349527cc90fe1cc9c5db9"]
]
}
]
],
"signatures": [
"a1489ddbe5046a39a95b012a06696e69742d3102146163636f756e745f6372656174696f6e5f66656510d0070000000000000354455354530000036b657921032d2a4af3e23294e0a1d9dbc46e0272d8e1977ce2ae3349527cc90fe1cc9c5db9000000"
],
"ref_block_num": 18593,
"extensions": []
}
28 changes: 26 additions & 2 deletions tests/steem/test_broadcast.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@ def test_claim_reward():


def test_witness_update():
# TODO: Remove when witness_update is fixed.
return
wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
c = Commit(steemd_instance=Steemd(nodes=[]),
keys=[wif])
Expand All @@ -65,3 +63,29 @@ def test_witness_update():
raise Exception('expected RPCError')

assert 'tx_missing_active_auth' in rpc_error


def test_witness_set_properties():
wif = '5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3'
c = Commit(steemd_instance=Steemd(nodes=[]),
keys=[wif])

signing_key = 'STM1111111111111111111111111111111114T1Anm'
props = [
['account_creation_fee', 'd0070000000000000354455354530000'],
['key', ('032d2a4af3e23294e0a1d9dbc46e0272d'
'8e1977ce2ae3349527cc90fe1cc9c5db9')]
]

rpc_error = None
try:
c.witness_set_properties(
signing_key=signing_key,
props=props,
account='test')
except RPCError as e:
rpc_error = str(e)
else:
raise Exception('expected RPCError')

assert 'tx_missing_other_auth' in rpc_error
2 changes: 1 addition & 1 deletion tests/steem/test_steemd.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def test_get_version():
s = Steemd()
response = s.call('get_version', api='login_api')
version = response['blockchain_version']
assert version[0:4] == '0.19'
assert version[0:4] == '0.20'


def test_get_dgp():
Expand Down
26 changes: 26 additions & 0 deletions tests/steem/test_transactions.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,32 @@ def test_witness_update(self):
"b9f2405478badadb4c")
self.assertEqual(compare[:-130], tx_wire[:-130])

def test_witness_set_properties(self):
op = operations.WitnessSetProperties(**{
"owner": "init-1",
"props": [
["account_creation_fee", "d0070000000000000354455354530000"],
["key", ("032d2a4af3e23294e0a1d9dbc46e0272d"
"8e1977ce2ae3349527cc90fe1cc9c5db9")]
]
})
ops = [operations.Operation(op)]
tx = SignedTransaction(
ref_block_num=ref_block_num,
ref_block_prefix=ref_block_prefix,
expiration=expiration,
operations=ops)
tx = tx.sign([wif], chain=self.steem.chain_params)
tx_wire = hexlify(compat_bytes(tx)).decode("ascii")
compare = ("f68585abf4dce7c80457012a06696e69742d3102146163636f75"
"6e745f6372656174696f6e5f66656510d0070000000000000354"
"455354530000036b657921032d2a4af3e23294e0a1d9dbc46e02"
"72d8e1977ce2ae3349527cc90fe1cc9c5db90000011f7797b8f7"
"3e03c04d603512f278aeceb5f76de1d0c527052886df806badb0"
"e41f55a8321abc6431c38130cc789b992e6c79ed4d403eb5906d"
"5af6d3b83626a3e7")
self.assertEqual(compare[:-130], tx_wire[:-130])

def test_witness_vote(self):
op = operations.AccountWitnessVote(**{
"account": "xeroc",
Expand Down