Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
25 changes: 20 additions & 5 deletions devnet/singularity/cluster_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,26 +33,35 @@
"ENABLE_GENERAL_NATIVE_TOKEN_TIMESTAMP": 0,
"ROOT": {
"MAX_STALE_ROOT_BLOCK_HEIGHT_DIFF": 22500,
"CONSENSUS_TYPE": "POW_SIMULATE",
"CONSENSUS_TYPE": "POW_ETHASH",
"CONSENSUS_CONFIG": {
"TARGET_BLOCK_TIME": 60,
"REMOTE_MINE": false
"REMOTE_MINE": true
},
"GENESIS": {
"VERSION": 0,
"HEIGHT": 0,
"HASH_PREV_BLOCK": "0000000000000000000000000000000000000000000000000000000000000000",
"HASH_MERKLE_ROOT": "0000000000000000000000000000000000000000000000000000000000000000",
"TIMESTAMP": 1556639999,
"DIFFICULTY": 10000000000000,
"DIFFICULTY": 100000,
"NONCE": 0
},
"COINBASE_ADDRESS": "000000000000000000000000000000000000000000000000",
"COINBASE_ADDRESS": "5C935469C5592Aeeac3372e922d9bCEabDF8830d00000000",
"COINBASE_AMOUNT": 156000000000000000000,
"DIFFICULTY_ADJUSTMENT_CUTOFF_TIME": 40,
"DIFFICULTY_ADJUSTMENT_FACTOR": 1024,
"EPOCH_INTERVAL": 525600,
"POSW_CONFIG": {
"ENABLED": true,
"ENABLE_TIMESTAMP": 1646668800,
"DIFF_DIVIDER": 100,
"WINDOW_SIZE": 512,
"TOTAL_STAKE_PER_BLOCK": 10000000000000000000000,
"BOOST_TIMESTAMP": 1647424800,
"BOOST_MULTIPLIER_PER_STEP": 2,
"BOOST_STEPS": 10,
"BOOST_STEP_INTERVAL": 3600
}
},
"CHAINS": [
Expand Down Expand Up @@ -81,6 +90,11 @@
"balances": {
"QKC": 600000000000000000000000000
}
},
"5C935469C5592Aeeac3372e922d9bCEabDF8830d00000000": {
"balances": {
"QKC": 600000000000000000000000000
}
}
}
},
Expand Down Expand Up @@ -351,7 +365,8 @@
}
],
"REWARD_TAX_RATE": 0.5,
"BLOCK_REWARD_DECAY_FACTOR": 0.88
"BLOCK_REWARD_DECAY_FACTOR": 0.88,
"ROOT_CHAIN_POSW_CONTRACT_BYTECODE_HASH": "ee90e568da573f251d63256e843add8bd7a27cec1f4c2a06ef20380be68df0a3"
},
"MASTER": {
"MASTER_TO_SLAVE_CONNECT_RETRY_DELAY": 1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,22 @@
"post": {
"ConstantinopleFix": [
{
"hash": "0x8c1cab0408d24a2eb99e95765c046878d2ff5fd6f221709a26845aca1add61d6",
"hash": "0x606816f0b9968977f7a593d6d17208b851ab868c6bc7a8034de434dbc4d2a344",
"indexes": {
"data": 0,
"gas": 0,
"value": 0,
"transferTokenId": 0
},
"logs": "0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347"
}
},
{
"hash": "0x2a39e58d7a961d2979249a7dab088b89c95a9e328ea6d344b6ebb89031b4ac39",
"indexes": {
"data": 1,
"gas": 0,
"value": 0,
"transferTokenId": 0
}
}
]
},
Expand All @@ -45,14 +53,14 @@
"0x8bb0": "0x0f7832d890000",
"0x1234": "0x9"
},
"code": "608060405234801561001057600080fd5b5061010e806100206000396000f3fe608060405260043610603e5763ffffffff7c010000000000000000000000000000000000000000000000000000000060003504166390b4902781146043575b600080fd5b348015604e57600080fd5b50607560048036036060811015606357600080fd5b50803590602081013590604001356087565b60408051918252519081900360200190f35b6000608f60c3565b84815260208082018590526040820184905282606083600064514b430002600019f1151560bb57600080fd5b509392505050565b606060405190810160405280600390602082028038833950919291505056fea165627a7a72305820140e93e6d0727652332a820d62917a2091a3e807df1d9a454a1ebe542e25592a0029",
"code": "0x608060405234801561001057600080fd5b506004361061002b5760003560e01c806390b4902714610030575b600080fd5b6100706004803603606081101561004657600080fd5b81019080803590602001909291908035906020019092919080359060200190929190505050610086565b6040518082815260200191505060405180910390f35b60006100906100f8565b848160006003811061009e57fe5b60200201818152505083816001600381106100b557fe5b60200201818152505082816002600381106100cc57fe5b602002018181525050602082606083600064514b430002600019f16100f057600080fd5b509392505050565b604051806060016040528060039060208202803883398082019150509050509056fea265627a7a723158208279dcc675268973e1d770d00f53c1c4028ba89a3f47d630884e9dd77af9c25c64736f6c63430005110032",
"nonce": "0x00",
"storage": {
}
},
"0xbfd5b36fa6f5de48d807397e9b68d0a0d694e38e": {
"balance": "0x00",
"code": "6080604052348015600f57600080fd5b50606f80601d6000396000f3fe6080604052600a6024565b6040816000808064514b430001600019f150506001600055005b602060405190810160405280600190602082028038833950919291505056fea165627a7a72305820b402355b87dfda3dd5a1faa36cb6f0ef8f317cac5d280661af787367d1f8b8dc0029",
"code": "0x6080604052600a6028565b604081600080600064514b430001600019f150600160008190555050005b604051806020016040528060019060208202803883398082019150509050509056fea265627a7a723158203c7281fa897cd5f97a5c8e50b85d8d4b5775c642d24f1f56813223533e629f3b64736f6c63430005110032",
"nonce": "0x00",
"storage": {
}
Expand All @@ -64,14 +72,16 @@
"_hex": "0xbfd5b36fa6f5de48d807397e9b68d0a0d694e38e"
},
"uint256 token_id": {
"_hex": "0x1234"
"_hex": "0x1234",
"_hex2": "1046823949374975479359571919336054293237424652288"
},
"uint256 value": {
"_hex": "0x09"
}
},
"data": [
"0x90b49027000000000000000000000000bfd5b36fa6f5de48d807397e9b68d0a0d694e38e00000000000000000000000000000000000000000000000000000000000012340000000000000000000000000000000000000000000000000000000000000009"
"0x90b49027000000000000000000000000bfd5b36fa6f5de48d807397e9b68d0a0d694e38e00000000000000000000000000000000000000000000000000000000000012340000000000000000000000000000000000000000000000000000000000000009",
"0x90b49027000000000000000000000000bfd5b36fa6f5de48d807397e9b68d0a0d694e38e000000000000000000000000b75d3598fd4950000000000043a3163a810700000000000000000000000000000000000000000000000000000000000000000009"
],
"gasLimit": [
"0x2dc6c0"
Expand Down
13 changes: 12 additions & 1 deletion mainnet/singularity/cluster_config_bootnodes.json
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,18 @@
"COINBASE_AMOUNT": 156000000000000000000,
"DIFFICULTY_ADJUSTMENT_CUTOFF_TIME": 40,
"DIFFICULTY_ADJUSTMENT_FACTOR": 1024,
"EPOCH_INTERVAL": 525600
"EPOCH_INTERVAL": 525600,
"POSW_CONFIG": {
"ENABLED": true,
"ENABLE_TIMESTAMP": 1569567600,
"DIFF_DIVIDER": 10000,
"WINDOW_SIZE": 512,
"TOTAL_STAKE_PER_BLOCK": 1000000000000000000000000,
"BOOST_TIMESTAMP": 1649736000,
"BOOST_MULTIPLIER_PER_STEP": 2,
"BOOST_STEPS": 13,
"BOOST_STEP_INTERVAL": 86400
}
},
"CHAINS": [
{
Expand Down
6 changes: 5 additions & 1 deletion mainnet/singularity/cluster_config_template.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@
"ENABLE_TIMESTAMP": 1569567600,
"DIFF_DIVIDER": 10000,
"WINDOW_SIZE": 512,
"TOTAL_STAKE_PER_BLOCK": 1000000000000000000000000
"TOTAL_STAKE_PER_BLOCK": 1000000000000000000000000,
"BOOST_TIMESTAMP": 1649736000,
"BOOST_MULTIPLIER_PER_STEP": 2,
"BOOST_STEPS": 13,
"BOOST_STEP_INTERVAL": 86400
}
},
"CHAINS": [
Expand Down
6 changes: 5 additions & 1 deletion mainnet/singularity/cluster_config_template_8nodes.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,11 @@
"ENABLE_TIMESTAMP": 1569567600,
"DIFF_DIVIDER": 10000,
"WINDOW_SIZE": 512,
"TOTAL_STAKE_PER_BLOCK": 1000000000000000000000000
"TOTAL_STAKE_PER_BLOCK": 1000000000000000000000000,
"BOOST_TIMESTAMP": 1649736000,
"BOOST_MULTIPLIER_PER_STEP": 2,
"BOOST_STEPS": 13,
"BOOST_STEP_INTERVAL": 86400
}
},
"CHAINS": [
Expand Down
Binary file added papers/universal_v3_staking.pdf
Binary file not shown.
4 changes: 2 additions & 2 deletions quarkchain/cluster/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ async def get_stats(self):
shard["poswEnabled"] = config.ENABLED
shard["poswMinStake"] = config.TOTAL_STAKE_PER_BLOCK
shard["poswWindowSize"] = config.WINDOW_SIZE
shard["difficultyDivider"] = config.DIFF_DIVIDER
shard["difficultyDivider"] = config.get_diff_divider(shard_stats.timestamp)
shards.append(shard)
shards.sort(key=lambda x: x["fullShardId"])

Expand Down Expand Up @@ -1685,7 +1685,7 @@ async def get_work(
check(isinstance(block, RootBlock))
posw_mineable = await self.posw_mineable(block)
config = self.env.quark_chain_config.ROOT.POSW_CONFIG
return work, config.DIFF_DIVIDER if posw_mineable else None
return work, config.get_diff_divider(block.header.create_time) if posw_mineable else None

if branch.value not in self.branch_to_slaves:
return None, None
Expand Down
2 changes: 1 addition & 1 deletion quarkchain/cluster/posw.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ def get_posw_info(

diff = header.difficulty
ret = lambda success: PoSWInfo(
diff // config.DIFF_DIVIDER if success else diff,
diff // config.get_diff_divider(header.create_time) if success else diff,
block_threshold,
# mined blocks should include current one, assuming success
posw_mined_blocks=cnt + 1,
Expand Down
2 changes: 1 addition & 1 deletion quarkchain/cluster/root_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ def __init__(self, db, quark_chain_config, count_minor_blocks=False):
self.tip_header = None

self.__recover_from_db()
self.rblock_cache = LRUCache(maxsize=1024)
self.rblock_cache = LRUCache(maxsize=8192) # enough for 8192 * 60 / 3600 / 24 = 5.6 days

def __recover_from_db(self):
""" Recover the best chain from local database.
Expand Down
2 changes: 1 addition & 1 deletion quarkchain/cluster/shard.py
Original file line number Diff line number Diff line change
Expand Up @@ -406,7 +406,7 @@ def __validate_block_headers(self, block_header_list: List[MinorBlockHeader]):
consensus_type = shard_config.CONSENSUS_TYPE
diff = header.difficulty
if shard_config.POSW_CONFIG.ENABLED:
diff //= shard_config.POSW_CONFIG.DIFF_DIVIDER
diff //= shard_config.POSW_CONFIG.get_diff_divider(header.create_time)
validate_seal(
header,
consensus_type,
Expand Down
2 changes: 1 addition & 1 deletion quarkchain/cluster/shard_db_operator.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def __init__(self, db, env, branch: Branch):

# height -> set(minor block hash) for counting wasted blocks
self.height_to_minor_block_hashes = dict()
self.rblock_cache = LRUCache(maxsize=256)
self.rblock_cache = LRUCache(maxsize=4096) # enough for 4096 * 60 / 3600 / 24 = 2.84 days
self.mblock_cache = LRUCache(maxsize=4096)
self.mblock_header_cache = LRUCache(maxsize=10240)

Expand Down
25 changes: 20 additions & 5 deletions quarkchain/cluster/shard_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -1183,26 +1183,32 @@ def get_next_block_coinbase_amount(self):
# TODO: add x-shard tx
return coinbase

def __get_all_unconfirmed_header_list(self) -> List[MinorBlockHeader]:
def __get_unconfirmed_header_list(self, max_blocks) -> List[MinorBlockHeader]:
"""height in ascending order"""
header_list = []
header = self.header_tip
start_height = (
self.confirmed_header_tip.height if self.confirmed_header_tip else -1
)
for i in range(header.height - start_height):
header_list.append(header)
steps = header.height - start_height
Logger.debug("{} blocks to be confirm".format(steps))
max_height = start_height + max_blocks
st = time_ms()
for i in range(steps):
if header.height <= max_height:
header_list.append(header)
header = self.db.get_minor_block_header_by_hash(
header.hash_prev_minor_block
)
Logger.debug("get_unconfirmed_header_list: unconfirmed header {}, max_blocks = {}, time use {} ms."
.format(steps, max_blocks, time_ms() - st))
check(header == self.confirmed_header_tip)
header_list.reverse()
return header_list

def get_unconfirmed_header_list(self) -> List[MinorBlockHeader]:
headers = self.__get_all_unconfirmed_header_list()
max_blocks = self.__get_max_blocks_in_one_root_block()
return headers[0:max_blocks]
return self.__get_unconfirmed_header_list(max_blocks)

def get_unconfirmed_headers_coinbase_amount(self) -> int:
"""only returns genesis token coinbase amount
Expand Down Expand Up @@ -1320,6 +1326,15 @@ def create_block_to_mine(
# Cross-shard receive must be handled before including tx from tx_queue
# This is part of consensus.
block.header.hash_prev_root_block = self.root_tip.get_hash()

# Move up to 100 rblock to prevent xchain cursor running out
prev_block_rblock = self.db.get_root_block_header_by_hash(prev_block.header.hash_prev_root_block)
assert (self.root_tip.height >= prev_block_rblock.height) # may further assert they are chained?
if (self.root_tip.height - prev_block_rblock.height > 100):
block.header.hash_prev_root_block = self.db.get_root_block_header_by_height(
block.header.hash_prev_root_block,
prev_block_rblock.height + 100
).get_hash()
(
xtx_list,
evm_state.xshard_tx_cursor_info,
Expand Down
1 change: 1 addition & 0 deletions quarkchain/cluster/tests/test_cluster.py
Original file line number Diff line number Diff line change
Expand Up @@ -2502,6 +2502,7 @@ def add_root_block(addr, sign=False):
qkc_config.ROOT.POSW_CONFIG.WINDOW_SIZE = 2
# should always pass pow check if posw is applied
qkc_config.ROOT.POSW_CONFIG.DIFF_DIVIDER = 1000000
qkc_config.ROOT.POSW_CONFIG.BOOST_TIMESTAMP = 0
shard = next(iter(clusters[0].slave_list[0].shards.values()))

# monkey patch staking results
Expand Down
19 changes: 19 additions & 0 deletions quarkchain/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,21 @@ class POSWConfig(BaseConfig):
# TODO: needs better tuning / estimating
# = total stakes / alpha
TOTAL_STAKE_PER_BLOCK = (10 ** 9) * QUARKSH_TO_JIAOZI
BOOST_TIMESTAMP = 0 # 0 mean Disable
BOOST_MULTIPLIER_PER_STEP = 2
BOOST_STEPS = 10
BOOST_STEP_INTERVAL = 43200

def get_diff_divider(self, block_timestamp):
diff_divider = self.DIFF_DIVIDER
if 0 < self.BOOST_TIMESTAMP <= block_timestamp:
steps = (block_timestamp - self.BOOST_TIMESTAMP) // self.BOOST_STEP_INTERVAL + 1
if steps > self.BOOST_STEPS:
steps = self.BOOST_STEPS

diff_divider = self.DIFF_DIVIDER * pow(self.BOOST_MULTIPLIER_PER_STEP, steps)

return diff_divider


class ChainConfig(BaseConfig):
Expand Down Expand Up @@ -251,6 +266,10 @@ def __init__(self):
self.POSW_CONFIG.WINDOW_SIZE = 4320 # 72 hours
self.POSW_CONFIG.DIFF_DIVIDER = 1000
self.POSW_CONFIG.TOTAL_STAKE_PER_BLOCK = 240000 * QUARKSH_TO_JIAOZI
self.POSW_CONFIG.BOOST_TIMESTAMP = 0
self.POSW_CONFIG.BOOST_MULTIPLIER_PER_STEP = 2
self.POSW_CONFIG.BOOST_STEPS = 10
self.POSW_CONFIG.BOOST_STEP_INTERVAL = 172800

def to_dict(self):
ret = super().to_dict()
Expand Down
2 changes: 1 addition & 1 deletion quarkchain/evm/tests/new_statetest_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def compute_state_test_unit(state, txdata, indices, konfig, is_qkc_state, qkc_en
tx.v = parse_int_or_hex(txdata["v"])
tx._in_mutable_context = False
# Run it
prev = state.to_dict()
prev = copy.deepcopy(state.to_dict())
success, output = apply_transaction(state, tx, tx_wrapper_hash=bytes(32))
except InvalidTransaction as e:
print("Exception: %r" % e)
Expand Down
Loading