Sitelet https://github.com/VIZ-Blockchain/viz-python-lib/commit/621540c4b659038c21972bf26b278279adc3218b
Skip to content

Commit 621540c

Browse files
committed
Add v4/v5 versioned_chain_properties variants (#342)
Add the chain_properties_hf13 (variant 4) and chain_properties_pm (variant 5, HF14/Onix) serializers to versioned_chain_properties. Variant 5 appends the ~47 PM governance params (oracle economics, disputes, batch/commit-reveal, lazy pool, leverage, GC) in FC_REFLECT_DERIVED(chain_properties_pm) order. - objects.py: refactor the shared chain-properties field list into helpers (_chain_properties_hf9/hf13/pm_items); ChainProperties(3) / ChainPropertiesHf13(4) / ChainPropertiesPm(5) reuse them. ChainPropertiesVariant now selects the variant index from the fields present (pm_* -> 5, distribution_epoch_length -> 4, else 3). Import Uint8/Bool. - tests: byte-exact v4/v5 serialization, self-contained (no live node). Cross-checked: v4 and v5 serialize identically to viz-php-lib build_versioned_chain_properties_update. Full suite 175 passed / 1 skipped / 1 xfailed; ruff clean. The live round-trip test (test_versioned_chain_properties_update) stays xfail until the testnet image is rebuilt with the validator-renamed schema.
1 parent 88def4c commit 621540c

2 files changed

Lines changed: 250 additions & 46 deletions

File tree

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
"""Byte-exact serialization tests for versioned_chain_properties variants 4 and 5.
2+
3+
Self-contained (no live node): the expected hex is byte-for-byte identical to
4+
viz-php-lib build_versioned_chain_properties_update($owner,$props,$version)
5+
output, which mirrors FC_REFLECT_DERIVED(chain_properties_hf13 / _pm) in the
6+
node. Variant index == C++ static_variant index (4 = hf13, 5 = pm/HF14 Onix).
7+
8+
The live round-trip check against a node lives in test_serialization.py
9+
(test_versioned_chain_properties_update, xfail until the testnet image is
10+
rebuilt with the validator-renamed schema).
11+
"""
12+
13+
from vizbase.objects import Operation
14+
15+
_BASE = {
16+
"account_creation_fee": "1.000 VIZ",
17+
"maximum_block_size": 65536,
18+
"create_account_delegation_ratio": 10,
19+
"create_account_delegation_time": 2592000,
20+
"min_delegation": "1.000 VIZ",
21+
"min_curation_percent": 0,
22+
"max_curation_percent": 10000,
23+
"bandwidth_reserve_percent": 0,
24+
"bandwidth_reserve_below": "0.000000 SHARES",
25+
"flag_energy_additional_cost": 0,
26+
"vote_accounting_min_rshares": 100000,
27+
"committee_request_approve_min_percent": 1000,
28+
"inflation_validator_percent": 2000,
29+
"inflation_ratio_committee_vs_reward_fund": 5000,
30+
"inflation_recalc_period": 806400,
31+
"data_operations_cost_additional_bandwidth": 10000,
32+
"validator_miss_penalty_percent": 100,
33+
"validator_miss_penalty_duration": 86400,
34+
"create_invite_min_balance": "10.000 VIZ",
35+
"committee_create_request_fee": "100.000 VIZ",
36+
"create_paid_subscription_fee": "100.000 VIZ",
37+
"account_on_sale_fee": "10.000 VIZ",
38+
"subaccount_on_sale_fee": "100.000 VIZ",
39+
"validator_declaration_fee": "10.000 VIZ",
40+
"withdraw_intervals": 28,
41+
"distribution_epoch_length": 28800, # hf13 → selects variant 4
42+
}
43+
44+
_PM = {
45+
"pm_oracle_registration_fee": "10.000 VIZ",
46+
"pm_min_oracle_insurance": "5000.000 VIZ",
47+
"pm_market_creation_fee": "5.000 VIZ",
48+
"pm_min_liquidity": "100.000 VIZ",
49+
"pm_max_outcomes": 10,
50+
"pm_max_market_duration": 31536000,
51+
"pm_max_oracle_fee_percent": 500,
52+
"pm_oracle_accept_window_sec": 3600,
53+
"pm_listing_min_coverage_percent": 250,
54+
"pm_betting_min_coverage_percent": 150,
55+
"pm_default_time_penalty_percent": 50,
56+
"pm_max_time_penalty": 1000000,
57+
"pm_dispute_fee": "1000.000 VIZ",
58+
"pm_dispute_grace_sec": 43200,
59+
"pm_oracle_dispute_response_sec": 43200,
60+
"pm_dispute_auto_close_sec": 1209600,
61+
"pm_dispute_vote_period_sec": 259200,
62+
"pm_dispute_approve_min_percent": 1000,
63+
"pm_oracle_penalty_percent": 500,
64+
"pm_no_contest_penalty_percent": 5000,
65+
"pm_dispute_reward_multiplier": 30000,
66+
"pm_batch_epoch_blocks": 20,
67+
"pm_reveal_window_blocks": 200,
68+
"pm_commit_no_reveal_penalty_percent": 2000,
69+
"pm_min_batch_bet": "1.000 VIZ",
70+
"pm_commit_reveal_enabled": True,
71+
"pm_processing_cap_per_block": 200,
72+
"pm_lazy_pool_enabled": True,
73+
"pm_lazy_alloc_percent": 2000,
74+
"pm_lazy_max_total_alloc_percent": 7000,
75+
"pm_lazy_lock_sec": 604800,
76+
"pm_lazy_recall_step_percent": 1000,
77+
"pm_lazy_emergency_penalty_percent": 5000,
78+
"pm_lazy_min_liquidity_fee_percent": 200,
79+
"pm_leverage_enabled": False,
80+
"pm_leverage_fund_percent": 10,
81+
"pm_leverage_max_per_position_bp": 20,
82+
"pm_leverage_pool_profit_percent": 10,
83+
"pm_leverage_safety_margin_percent": 1,
84+
"pm_leverage_max_slippage_percent": 10,
85+
"pm_leverage_min_market_liquidity": "5000.000 VIZ",
86+
"pm_leverage_max_position_ratio_percent": 5,
87+
"pm_leverage_expiration_buffer_sec": 86400,
88+
"pm_leverage_m_factor_percent": 50,
89+
"pm_leverage_funding_rate_ppm_per_day": 50,
90+
"pm_conversion_profit_cost_percent": 50,
91+
"pm_closed_market_retention_sec": 432000,
92+
}
93+
94+
_V4_HEX = (
95+
"2e05616c69636504e8030000000000000356495a00000000000001000a000000008d2700e8030000000000000356495a"
96+
"00000000000010270000000000000000000006534841524553000000a0860100e803d0078813004e0c00102700006400"
97+
"8051010010270000000000000356495a00000000a0860100000000000356495a00000000a0860100000000000356495a"
98+
"0000000010270000000000000356495a00000000a0860100000000000356495a0000000010270000000000000356495a"
99+
"000000001c0080700000"
100+
)
101+
102+
_V5_HEX = (
103+
"2e05616c69636505e8030000000000000356495a00000000000001000a000000008d2700e8030000000000000356495a"
104+
"00000000000010270000000000000000000006534841524553000000a0860100e803d0078813004e0c00102700006400"
105+
"8051010010270000000000000356495a00000000a0860100000000000356495a00000000a0860100000000000356495a"
106+
"0000000010270000000000000356495a00000000a0860100000000000356495a0000000010270000000000000356495a"
107+
"000000001c008070000010270000000000000356495a00000000404b4c00000000000356495a000000008813000000000"
108+
"0000356495a00000000a0860100000000000356495a000000000a8033e101f401100e0000fa009600320040420f004042"
109+
"0f00000000000356495a00000000c0a80000c0a800000075120080f40300e803f40188133075000014000000c8000000d"
110+
"007e8030000000000000356495a0000000001c800000001d007581b803a0900e8038813c800000a0014000a0001000a00"
111+
"404b4c00000000000356495a00000000050080510100320032000000320080970600"
112+
)
113+
114+
115+
def test_versioned_chain_properties_v4():
116+
op = Operation(["versioned_chain_properties_update", {"owner": "alice", "props": dict(_BASE)}])
117+
assert bytes(op).hex() == _V4_HEX
118+
119+
120+
def test_versioned_chain_properties_v5_pm():
121+
op = Operation(["versioned_chain_properties_update", {"owner": "alice", "props": {**_BASE, **_PM}}])
122+
assert bytes(op).hex() == _V5_HEX

‎vizbase/objects.py‎

Lines changed: 128 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,13 @@
44
from graphenebase.objects import GrapheneObject, isArgsThisClass
55
from graphenebase.objects import Operation as GrapheneOperation
66
from graphenebase.types import (
7+
Bool,
78
Bytes,
89
Int16,
910
Map,
1011
Static_variant,
1112
String,
13+
Uint8,
1214
Uint16,
1315
Uint32,
1416
Uint64,
@@ -117,13 +119,124 @@ def __init__(self, *args, **kwargs):
117119

118120
class ChainPropertiesVariant(Static_variant):
119121
def __init__(self, props):
120-
version = 3
121-
data = ChainProperties(**props)
122+
# Pick the versioned_chain_properties variant (index == C++ static_variant
123+
# index) from the fields present. HF14/Onix (chain_properties_pm) = 5,
124+
# HF13 (chain_properties_hf13) = 4, HF9 (chain_properties_hf9) = 3.
125+
if "pm_oracle_registration_fee" in props:
126+
version = 5
127+
data = ChainPropertiesPm(**props)
128+
elif "distribution_epoch_length" in props:
129+
version = 4
130+
data = ChainPropertiesHf13(**props)
131+
else:
132+
version = 3
133+
data = ChainProperties(**props)
122134

123135
super().__init__(data, version)
124136

125137

138+
def _chain_properties_hf9_items(kwargs):
139+
"""Fields shared by chain_properties_hf9 (variant 3) and all later versions,
140+
in the exact FC_REFLECT order (binary layout is consensus-critical)."""
141+
return [
142+
# initial, version 0
143+
("account_creation_fee", Amount(kwargs["account_creation_fee"])),
144+
("maximum_block_size", Uint32(kwargs["maximum_block_size"])),
145+
("create_account_delegation_ratio", Uint32(kwargs["create_account_delegation_ratio"])),
146+
("create_account_delegation_time", Uint32(kwargs["create_account_delegation_time"])),
147+
("min_delegation", Amount(kwargs["min_delegation"])),
148+
("min_curation_percent", Uint16(kwargs["min_curation_percent"])),
149+
("max_curation_percent", Uint16(kwargs["max_curation_percent"])),
150+
("bandwidth_reserve_percent", Uint16(kwargs["bandwidth_reserve_percent"])),
151+
("bandwidth_reserve_below", Amount(kwargs["bandwidth_reserve_below"])),
152+
("flag_energy_additional_cost", Uint16(kwargs["flag_energy_additional_cost"])),
153+
("vote_accounting_min_rshares", Uint32(kwargs["vote_accounting_min_rshares"])),
154+
("committee_request_approve_min_percent", Uint16(kwargs["committee_request_approve_min_percent"])),
155+
# chain_properties_hf4, version 1
156+
("inflation_validator_percent", Uint16(kwargs["inflation_validator_percent"])),
157+
("inflation_ratio_committee_vs_reward_fund", Uint16(kwargs["inflation_ratio_committee_vs_reward_fund"])),
158+
("inflation_recalc_period", Uint32(kwargs["inflation_recalc_period"])),
159+
# chain_properties_hf6: version 2
160+
("data_operations_cost_additional_bandwidth", Uint32(kwargs["data_operations_cost_additional_bandwidth"])),
161+
("validator_miss_penalty_percent", Uint16(kwargs["validator_miss_penalty_percent"])),
162+
("validator_miss_penalty_duration", Uint32(kwargs["validator_miss_penalty_duration"])),
163+
# chain_properties_hf9: version 3
164+
("create_invite_min_balance", Amount(kwargs["create_invite_min_balance"])),
165+
("committee_create_request_fee", Amount(kwargs["committee_create_request_fee"])),
166+
("create_paid_subscription_fee", Amount(kwargs["create_paid_subscription_fee"])),
167+
("account_on_sale_fee", Amount(kwargs["account_on_sale_fee"])),
168+
("subaccount_on_sale_fee", Amount(kwargs["subaccount_on_sale_fee"])),
169+
("validator_declaration_fee", Amount(kwargs["validator_declaration_fee"])),
170+
("withdraw_intervals", Uint16(kwargs["withdraw_intervals"])),
171+
]
172+
173+
174+
def _chain_properties_hf13_items(kwargs):
175+
"""hf9 + chain_properties_hf13 (variant 4)."""
176+
return _chain_properties_hf9_items(kwargs) + [
177+
("distribution_epoch_length", Uint32(kwargs["distribution_epoch_length"])),
178+
]
179+
180+
181+
def _chain_properties_pm_items(kwargs):
182+
"""hf13 + HF14/Onix chain_properties_pm (variant 5) governance params.
183+
Order/types mirror FC_REFLECT_DERIVED(chain_properties_pm) exactly."""
184+
return _chain_properties_hf13_items(kwargs) + [
185+
("pm_oracle_registration_fee", Amount(kwargs["pm_oracle_registration_fee"])),
186+
("pm_min_oracle_insurance", Amount(kwargs["pm_min_oracle_insurance"])),
187+
("pm_market_creation_fee", Amount(kwargs["pm_market_creation_fee"])),
188+
("pm_min_liquidity", Amount(kwargs["pm_min_liquidity"])),
189+
("pm_max_outcomes", Uint8(kwargs["pm_max_outcomes"])),
190+
("pm_max_market_duration", Uint32(kwargs["pm_max_market_duration"])),
191+
("pm_max_oracle_fee_percent", Uint16(kwargs["pm_max_oracle_fee_percent"])),
192+
("pm_oracle_accept_window_sec", Uint32(kwargs["pm_oracle_accept_window_sec"])),
193+
("pm_listing_min_coverage_percent", Uint16(kwargs["pm_listing_min_coverage_percent"])),
194+
("pm_betting_min_coverage_percent", Uint16(kwargs["pm_betting_min_coverage_percent"])),
195+
("pm_default_time_penalty_percent", Uint16(kwargs["pm_default_time_penalty_percent"])),
196+
("pm_max_time_penalty", Uint32(kwargs["pm_max_time_penalty"])),
197+
("pm_dispute_fee", Amount(kwargs["pm_dispute_fee"])),
198+
("pm_dispute_grace_sec", Uint32(kwargs["pm_dispute_grace_sec"])),
199+
("pm_oracle_dispute_response_sec", Uint32(kwargs["pm_oracle_dispute_response_sec"])),
200+
("pm_dispute_auto_close_sec", Uint32(kwargs["pm_dispute_auto_close_sec"])),
201+
("pm_dispute_vote_period_sec", Uint32(kwargs["pm_dispute_vote_period_sec"])),
202+
("pm_dispute_approve_min_percent", Uint16(kwargs["pm_dispute_approve_min_percent"])),
203+
("pm_oracle_penalty_percent", Uint16(kwargs["pm_oracle_penalty_percent"])),
204+
("pm_no_contest_penalty_percent", Uint16(kwargs["pm_no_contest_penalty_percent"])),
205+
("pm_dispute_reward_multiplier", Uint32(kwargs["pm_dispute_reward_multiplier"])),
206+
("pm_batch_epoch_blocks", Uint32(kwargs["pm_batch_epoch_blocks"])),
207+
("pm_reveal_window_blocks", Uint32(kwargs["pm_reveal_window_blocks"])),
208+
("pm_commit_no_reveal_penalty_percent", Uint16(kwargs["pm_commit_no_reveal_penalty_percent"])),
209+
("pm_min_batch_bet", Amount(kwargs["pm_min_batch_bet"])),
210+
("pm_commit_reveal_enabled", Bool(bool(kwargs["pm_commit_reveal_enabled"]))),
211+
("pm_processing_cap_per_block", Uint32(kwargs["pm_processing_cap_per_block"])),
212+
("pm_lazy_pool_enabled", Bool(bool(kwargs["pm_lazy_pool_enabled"]))),
213+
("pm_lazy_alloc_percent", Uint16(kwargs["pm_lazy_alloc_percent"])),
214+
("pm_lazy_max_total_alloc_percent", Uint16(kwargs["pm_lazy_max_total_alloc_percent"])),
215+
("pm_lazy_lock_sec", Uint32(kwargs["pm_lazy_lock_sec"])),
216+
("pm_lazy_recall_step_percent", Uint16(kwargs["pm_lazy_recall_step_percent"])),
217+
("pm_lazy_emergency_penalty_percent", Uint16(kwargs["pm_lazy_emergency_penalty_percent"])),
218+
("pm_lazy_min_liquidity_fee_percent", Uint16(kwargs["pm_lazy_min_liquidity_fee_percent"])),
219+
("pm_leverage_enabled", Bool(bool(kwargs["pm_leverage_enabled"]))),
220+
("pm_leverage_fund_percent", Uint16(kwargs["pm_leverage_fund_percent"])),
221+
("pm_leverage_max_per_position_bp", Uint16(kwargs["pm_leverage_max_per_position_bp"])),
222+
("pm_leverage_pool_profit_percent", Uint16(kwargs["pm_leverage_pool_profit_percent"])),
223+
("pm_leverage_safety_margin_percent", Uint16(kwargs["pm_leverage_safety_margin_percent"])),
224+
("pm_leverage_max_slippage_percent", Uint16(kwargs["pm_leverage_max_slippage_percent"])),
225+
("pm_leverage_min_market_liquidity", Amount(kwargs["pm_leverage_min_market_liquidity"])),
226+
("pm_leverage_max_position_ratio_percent", Uint16(kwargs["pm_leverage_max_position_ratio_percent"])),
227+
("pm_leverage_expiration_buffer_sec", Uint32(kwargs["pm_leverage_expiration_buffer_sec"])),
228+
("pm_leverage_m_factor_percent", Uint16(kwargs["pm_leverage_m_factor_percent"])),
229+
("pm_leverage_funding_rate_ppm_per_day", Uint32(kwargs["pm_leverage_funding_rate_ppm_per_day"])),
230+
("pm_conversion_profit_cost_percent", Uint16(kwargs["pm_conversion_profit_cost_percent"])),
231+
("pm_closed_market_retention_sec", Uint32(kwargs["pm_closed_market_retention_sec"])),
232+
]
233+
234+
126235
class ChainProperties(GrapheneObject):
236+
"""versioned_chain_properties variant 3 (chain_properties_hf9)."""
237+
238+
_items = staticmethod(_chain_properties_hf9_items)
239+
127240
def __init__(self, *args, **kwargs):
128241
if isArgsThisClass(self, args):
129242
self.data = args[0].data
@@ -137,50 +250,19 @@ def __init__(self, *args, **kwargs):
137250
context="chain_properties_update",
138251
)
139252

140-
super().__init__(
141-
OrderedDict(
142-
[
143-
# initial, version 0
144-
("account_creation_fee", Amount(kwargs["account_creation_fee"])),
145-
("maximum_block_size", Uint32(kwargs["maximum_block_size"])),
146-
("create_account_delegation_ratio", Uint32(kwargs["create_account_delegation_ratio"])),
147-
("create_account_delegation_time", Uint32(kwargs["create_account_delegation_time"])),
148-
("min_delegation", Amount(kwargs["min_delegation"])),
149-
("min_curation_percent", Uint16(kwargs["min_curation_percent"])),
150-
("max_curation_percent", Uint16(kwargs["max_curation_percent"])),
151-
("bandwidth_reserve_percent", Uint16(kwargs["bandwidth_reserve_percent"])),
152-
("bandwidth_reserve_below", Amount(kwargs["bandwidth_reserve_below"])),
153-
("flag_energy_additional_cost", Uint16(kwargs["flag_energy_additional_cost"])),
154-
("vote_accounting_min_rshares", Uint32(kwargs["vote_accounting_min_rshares"])),
155-
(
156-
"committee_request_approve_min_percent",
157-
Uint16(kwargs["committee_request_approve_min_percent"]),
158-
),
159-
# chain_properties_hf4, version 1
160-
("inflation_validator_percent", Uint16(kwargs["inflation_validator_percent"])),
161-
(
162-
"inflation_ratio_committee_vs_reward_fund",
163-
Uint16(kwargs["inflation_ratio_committee_vs_reward_fund"]),
164-
),
165-
("inflation_recalc_period", Uint32(kwargs["inflation_recalc_period"])),
166-
# chain_properties_hf6: version 2
167-
(
168-
"data_operations_cost_additional_bandwidth",
169-
Uint32(kwargs["data_operations_cost_additional_bandwidth"]),
170-
),
171-
("validator_miss_penalty_percent", Uint16(kwargs["validator_miss_penalty_percent"])),
172-
("validator_miss_penalty_duration", Uint32(kwargs["validator_miss_penalty_duration"])),
173-
# chain_properties_hf9: version 3
174-
("create_invite_min_balance", Amount(kwargs["create_invite_min_balance"])),
175-
("committee_create_request_fee", Amount(kwargs["committee_create_request_fee"])),
176-
("create_paid_subscription_fee", Amount(kwargs["create_paid_subscription_fee"])),
177-
("account_on_sale_fee", Amount(kwargs["account_on_sale_fee"])),
178-
("subaccount_on_sale_fee", Amount(kwargs["subaccount_on_sale_fee"])),
179-
("validator_declaration_fee", Amount(kwargs["validator_declaration_fee"])),
180-
("withdraw_intervals", Uint16(kwargs["withdraw_intervals"])),
181-
]
182-
)
183-
)
253+
super().__init__(OrderedDict(self._items(kwargs)))
254+
255+
256+
class ChainPropertiesHf13(ChainProperties):
257+
"""versioned_chain_properties variant 4 (chain_properties_hf13)."""
258+
259+
_items = staticmethod(_chain_properties_hf13_items)
260+
261+
262+
class ChainPropertiesPm(ChainProperties):
263+
"""versioned_chain_properties variant 5 (chain_properties_pm, HF14/Onix)."""
264+
265+
_items = staticmethod(_chain_properties_pm_items)
184266

185267

186268
class Op_wrapper(GrapheneObject):

0 commit comments

Comments
 (0)