Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions mainnet/singularity/cluster_config_bootnodes.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"ENABLE_NON_RESERVED_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_POSW_STAKING_DECAY_TIMESTAMP": 1588291200,
"ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP": 1746060000,
Comment thread
ping-ke marked this conversation as resolved.
Outdated
"TX_WHITELIST_SENDERS": [
"b8C082828F51343299c9A4deEb2503AaC3bA074f",
"3391A1796cB98D79A2Fde326F375DF900C959Ed0",
Expand Down
1 change: 1 addition & 0 deletions mainnet/singularity/cluster_config_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"ENABLE_NON_RESERVED_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_POSW_STAKING_DECAY_TIMESTAMP": 1588291200,
"ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP": 1746060000,
"TX_WHITELIST_SENDERS": [
"b8C082828F51343299c9A4deEb2503AaC3bA074f",
"3391A1796cB98D79A2Fde326F375DF900C959Ed0",
Expand Down
1 change: 1 addition & 0 deletions mainnet/singularity/cluster_config_template_8nodes.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
"ENABLE_NON_RESERVED_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP": 1588291200,
"ENABLE_POSW_STAKING_DECAY_TIMESTAMP": 1588291200,
"ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP": 1746060000,
"TX_WHITELIST_SENDERS": [
"b8C082828F51343299c9A4deEb2503AaC3bA074f",
"3391A1796cB98D79A2Fde326F375DF900C959Ed0",
Expand Down
21 changes: 20 additions & 1 deletion quarkchain/cluster/root_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -659,10 +659,29 @@ def get_posw_info(
if block.header.height == 0: # genesis
return None
config = self.root_config.POSW_CONFIG # type: POSWConfig
stake_per_block = config.TOTAL_STAKE_PER_BLOCK
enable_decay_ts = (
self.env.quark_chain_config.ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP
)
if enable_decay_ts is not None and block.header.create_time > enable_decay_ts:
stake_per_block = self.__decay_by_epoch(stake_per_block, block.header.height)
block_cnt = get_posw_coinbase_blockcnt(
config.WINDOW_SIZE,
self.coinbase_addr_cache,
block.header.hash_prev_block,
self.db.get_root_block_header_by_hash,
)
return get_posw_info(config, block.header, stakes, block_cnt, signer=signer)
return get_posw_info(config, block.header, stakes, block_cnt, stake_per_block, signer=signer)

def __decay_by_epoch(self, value: int, block_height: int):
epoch = (
block_height
// self.env.quark_chain_config.ROOT.EPOCH_INTERVAL
)
decay_numerator = (
self.env.quark_chain_config.block_reward_decay_factor.numerator ** epoch
)
decay_denominator = (
self.env.quark_chain_config.block_reward_decay_factor.denominator ** epoch
)
return value * decay_numerator // decay_denominator
31 changes: 31 additions & 0 deletions quarkchain/cluster/tests/test_root_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from quarkchain.cluster.root_state import RootState
from quarkchain.cluster.shard_state import ShardState
from quarkchain.cluster.tests.test_utils import get_test_env
from quarkchain.config import ConsensusType
from quarkchain.core import Address
from quarkchain.core import CrossShardTransactionList
from quarkchain.diff import EthDifficultyCalculator
Expand Down Expand Up @@ -717,3 +718,33 @@ def test_root_coinbase_decay(self):
* env.quark_chain_config.BLOCK_REWARD_DECAY_FACTOR ** 2
},
)

def test_root_posw_stake_by_block_decay_by_epoch(self):
acc_byte = b"\x01" * 20
acc = Address(acc_byte, full_shard_key=0)
env = get_test_env(genesis_account=acc, genesis_minor_quarkash=200)
r_state, s_states = create_default_state(env)
env.quark_chain_config.ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP = 100

r_state.root_config.CONSENSUS_TYPE = ConsensusType.POW_DOUBLESHA256
r_state.root_config.EPOCH_INTERVAL = 525600
r_state.root_config.POSW_CONFIG.TOTAL_STAKE_PER_BLOCK = 100
r_state.root_config.POSW_CONFIG.WINDOW_SIZE = 512
r_state.root_config.POSW_CONFIG.ENABLED = True

# created time is greater than threshold
b1 = r_state.get_tip_block().create_block_to_append(create_time=101, address=acc)
posw_info = r_state.get_posw_info(b1, 200, acc_byte)
# 200 qkc with 100 required per block, should equal 2 mineable blocks
self.assertIsNotNone(posw_info)
self.assertEqual(posw_info.posw_mineable_blocks, 200 / 100)

# decay (factor = 0.5) should kick in and double mineable blocks
b1.header.height = r_state.root_config.EPOCH_INTERVAL
posw_info = r_state.get_posw_info(b1, 200, acc_byte)
self.assertEqual(posw_info.posw_mineable_blocks, 200 / (100 / 2))

# no effect before the enable timestamp
b1.header.create_time = 99
posw_info = r_state.get_posw_info(b1, 200, acc_byte)
self.assertEqual(posw_info.posw_mineable_blocks, 200 / 100)
1 change: 1 addition & 0 deletions quarkchain/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,7 @@ class QuarkChainConfig(BaseConfig):
ENABLE_NON_RESERVED_NATIVE_TOKEN_TIMESTAMP = None
ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP = None
ENABLE_POSW_STAKING_DECAY_TIMESTAMP = None
ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP = None

MIN_TX_POOL_GAS_PRICE = 10 ** 9 # lowest gas price to accept, default 1 Gwei
MIN_MINING_GAS_PRICE = 10 ** 9 # lowest gas price to pack tx for mining, 1 Gwei
Expand Down
1 change: 1 addition & 0 deletions quarkchain/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
MAINNET_ENABLE_NON_RESERVED_NATIVE_TOKEN_CONTRACT_TIMESTAMP = 1588291200
MAINNET_ENABLE_GENERAL_NATIVE_TOKEN_CONTRACT_TIMESTAMP = 1588291200
MAINNET_ENABLE_POSW_STAKING_DECAY_TIMESTAMP = 1588291200
MAINNET_ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP = 1746060000 # 2025-05-01 08:40:00
MAINNET_ENABLE_EIP155_SIGNER_TIMESTAMP = 1625097600
MAINNET_BASE_ETH_CHAIN_ID = 100000

Expand Down
8 changes: 8 additions & 0 deletions quarkchain/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
MAINNET_ENABLE_NON_RESERVED_NATIVE_TOKEN_CONTRACT_TIMESTAMP,
MAINNET_ENABLE_GENERAL_NATIVE_TOKEN_CONTRACT_TIMESTAMP,
MAINNET_ENABLE_POSW_STAKING_DECAY_TIMESTAMP,
MAINNET_ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP,
MAINNET_ENABLE_EIP155_SIGNER_TIMESTAMP,
MAINNET_BASE_ETH_CHAIN_ID,
)
Expand Down Expand Up @@ -96,6 +97,13 @@ def cluster_config(self, c):
c.QUARKCHAIN.ENABLE_POSW_STAKING_DECAY_TIMESTAMP = (
MAINNET_ENABLE_POSW_STAKING_DECAY_TIMESTAMP
)
if (
c.QUARKCHAIN.ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP is None
and c.QUARKCHAIN.NETWORK_ID == 1
):
c.QUARKCHAIN.ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP = (
MAINNET_ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP
)
if (
c.QUARKCHAIN.ENABLE_EIP155_SIGNER_TIMESTAMP is None
and c.QUARKCHAIN.NETWORK_ID == 1
Expand Down
1 change: 1 addition & 0 deletions quarkchain/tests/test_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,6 +223,7 @@ def test_serialization(self):
"ENABLE_NON_RESERVED_NATIVE_TOKEN_TIMESTAMP": null,
"ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP": null,
"ENABLE_POSW_STAKING_DECAY_TIMESTAMP": null,
"ENABLE_ROOT_POSW_STAKING_DECAY_TIMESTAMP": null,
"MIN_TX_POOL_GAS_PRICE": 1000000000,
"MIN_MINING_GAS_PRICE": 1000000000,
"XSHARD_GAS_DDOS_FIX_ROOT_HEIGHT": 90000,
Expand Down