Skip to content

Commit

Permalink
Allow perpetual dft mining to correctly accept the next bitwork
Browse files Browse the repository at this point in the history
  • Loading branch information
Ardwin authored and Ardwin committed Jan 31, 2024
1 parent 997edd9 commit 84608d9
Show file tree
Hide file tree
Showing 4 changed files with 156 additions and 14 deletions.
2 changes: 2 additions & 0 deletions electrumx/lib/coins.py
Original file line number Diff line number Diff line change
Expand Up @@ -666,6 +666,7 @@ class Bitcoin(BitcoinMixin, Coin):
ATOMICALS_ACTIVATION_HEIGHT_DMINT = 819181
ATOMICALS_ACTIVATION_HEIGHT_COMMITZ = 822800
ATOMICALS_ACTIVATION_HEIGHT_DENSITY = 828128
ATOMICALS_ACTIVATION_HEIGHT_BITWORKEXT = 828500

@classmethod
def warn_old_client_on_tx_broadcast(cls, client_ver):
Expand Down Expand Up @@ -933,6 +934,7 @@ class BitcoinTestnet(BitcoinTestnetMixin, Coin):
ATOMICALS_ACTIVATION_HEIGHT_DMINT = 2540296
ATOMICALS_ACTIVATION_HEIGHT_COMMITZ = 2543936
ATOMICALS_ACTIVATION_HEIGHT_DENSITY = 2572729
ATOMICALS_ACTIVATION_HEIGHT_BITWORKEXT = 2576412

@classmethod
def warn_old_client_on_tx_broadcast(cls, client_ver):
Expand Down
16 changes: 15 additions & 1 deletion electrumx/lib/util_atomicals.py
Original file line number Diff line number Diff line change
Expand Up @@ -881,7 +881,6 @@ def format_name_type_candidates_to_rpc_for_subname(raw_entries, atomical_id_to_c
for base_candidate in reformatted:
dataset = atomical_id_to_candidate_info_map[compact_to_location_id_bytes(base_candidate['atomical_id'])]
base_atomical_id = base_candidate['atomical_id']
print(f'data atomical_id_to_candidate_info_map atomicalId= {base_atomical_id}')
base_candidate['payment'] = dataset.get('payment')
base_candidate['payment_type'] = dataset.get('payment_type')
base_candidate['payment_subtype'] = dataset.get('payment_subtype')
Expand Down Expand Up @@ -1664,6 +1663,21 @@ def get_subname_request_candidate_status(current_height, atomical_info, status,
'pending_candidate_atomical_id': candidate_id_compact
}

# Whether txid is valid for the current and next bitwork
def is_txid_valid_for_bitwork(txid, bitwork_vec, actual_mints, max_mints, target_increment, starting_target, allow_next):
expected_minimum_bitwork = calculate_expected_bitwork(bitwork_vec, actual_mints, max_mints, target_increment, starting_target)
if is_mint_pow_valid(txid, expected_minimum_bitwork):
return True, expected_minimum_bitwork

# If we allow the next bitwork also to be accepted
if allow_next:
remaining = max_mints - (actual_mints % max_mints)
expected_next_bitwork = calculate_expected_bitwork(bitwork_vec, actual_mints + remaining, max_mints, target_increment, starting_target)
if is_mint_pow_valid(txid, expected_next_bitwork):
return True, expected_next_bitwork

return False, None

def calculate_expected_bitwork(bitwork_vec, actual_mints, max_mints, target_increment, starting_target):
if starting_target < 64 or starting_target > 256:
raise Exception(f'Invalid starting target {starting_target}')
Expand Down
36 changes: 24 additions & 12 deletions electrumx/server/block_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@
is_seal_operation,
is_event_operation,
encode_atomical_ids_hex,
is_mint_pow_valid
is_mint_pow_valid,
is_txid_valid_for_bitwork
)

from electrumx.lib.atomicals_blueprint_builder import AtomicalsTransferBlueprintBuilder
Expand Down Expand Up @@ -2572,19 +2573,30 @@ def create_or_delete_decentralized_mint_output(self, atomicals_operations_found_

# If there was a commit bitwork required, then assess the stage of the minimum we expect to allow the mint
if mint_bitworkc_inc:
mint_bitworkc_start = mint_info_for_ticker.get('$mint_bitworkc_start')
expected_minimum_bitworkc = calculate_expected_bitwork(mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkc_inc, mint_bitworkc_start)
if not is_mint_pow_valid(atomicals_operations_found_at_inputs['commit_txid'], expected_minimum_bitworkc):
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkc_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, expected_minimum_bitworkc={expected_minimum_bitworkc}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None
mint_bitworkc_start = mint_info_for_ticker.get('$mint_bitworkc_start')
if height >= self.coin.ATOMICALS_ACTIVATION_HEIGHT_BITWORKEXT:
success, bitwork_str = is_txid_valid_for_bitwork(atomicals_operations_found_at_inputs['commit_txid'], mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkc_inc, mint_bitworkc_start, True)
if not success:
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkc_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None
else:
success, bitwork_str = is_txid_valid_for_bitwork(atomicals_operations_found_at_inputs['commit_txid'], mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkc_inc, mint_bitworkc_start, False)
if not success:
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkc_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None

# If there was a reveal bitwork required, then assess the stage of the minimum we expect to allow the mint
if mint_bitworkr_inc:
mint_bitworkr_start = mint_info_for_ticker.get('$mint_bitworkr_start')
expected_minimum_bitworkr = calculate_expected_bitwork(mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkr_inc, mint_bitworkr_start)
if not is_mint_pow_valid(atomicals_operations_found_at_inputs['reveal_location_txid'], expected_minimum_bitworkr):
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkr_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, expected_minimum_bitworkr={expected_minimum_bitworkr}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None

mint_bitworkr_start = mint_info_for_ticker.get('$mint_bitworkr_start')
if height >= self.coin.ATOMICALS_ACTIVATION_HEIGHT_BITWORKEXT:
if not is_txid_valid_for_bitwork(atomicals_operations_found_at_inputs['commit_txid'], mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkr_inc, mint_bitworkr_start, True):
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkc_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None
else:
if not is_txid_valid_for_bitwork(atomicals_operations_found_at_inputs['reveal_location_txid'], mint_bitwork_vec, decentralized_mints, max_mints, mint_bitworkr_inc, mint_bitworkr_start, False):
self.logger.warning(f'create_or_delete_decentralized_mint_output: mint_bitworkc_inc not is_mint_pow_valid {hash_to_hex_str(tx_hash)}, atomicals_operations_found_at_inputs={atomicals_operations_found_at_inputs}...')
return None

allow_mint = True
else:
# It is the 'fixed' mint mode and the bitworkc/r is static
Expand Down
116 changes: 115 additions & 1 deletion tests/lib/test_atomicals_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
derive_bitwork_prefix_from_target,
decode_bitwork_target_from_prefix,
is_bitwork_subset,
calculate_expected_bitwork
calculate_expected_bitwork,
is_txid_valid_for_bitwork
)

coin = Bitcoin
Expand Down Expand Up @@ -459,3 +460,116 @@ def test_calculate_expected_bitwork_base():
assert(calculate_expected_bitwork('abcdefe', 33000, 1000, 1, 127) == 'abcdefe000')
assert(calculate_expected_bitwork('abcdefe', 33000, 1000, 3, 127) == 'abcdefe0000000.2')

def test_calculate_expected_bitwork_rollover():

assert(calculate_expected_bitwork('888888888888', 49995, 3333, 1, 64) == '8888.15')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 49995, 3333, 1, 64, False)
assert(not success)
assert(not bitwork_str)

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 49995, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888')

assert(calculate_expected_bitwork('888888888888', 53189, 3333, 1, 64) == '8888.15')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53189, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888')

assert(calculate_expected_bitwork('888888888888', 53328, 3333, 1, 64) == '88888')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328, 3333, 1, 64, False)
assert(success)
assert(bitwork_str == '88888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888')

assert(calculate_expected_bitwork('888888888888', 53329, 3333, 1, 64) == '88888')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53329, 3333, 1, 64, False)
assert(success)
assert(bitwork_str == '88888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53329, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888')

assert(calculate_expected_bitwork('888888888888', 53328 + 3333, 3333, 1, 64) == '88888.1')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + 3333, 3333, 1, 64, False)
assert(success)
assert(bitwork_str == '88888.1')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + 3333, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888.1')

assert(calculate_expected_bitwork('888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64) == '88888.15')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64, False)
assert(not success)
assert(not bitwork_str)

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888f8888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64, False)
assert(success)
assert(bitwork_str == '88888.15')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888f8888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '88888.15')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64, False)
assert(not success)
assert(not bitwork_str)

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 53328 + (3333 * 16) - 1, 3333, 1, 64, True)
assert(success)
assert(bitwork_str == '888888')


assert(calculate_expected_bitwork('888888888888', 999, 1000, 64, 64) == '8888')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 999, 1000, 64, 64, False)
assert(success)
assert(bitwork_str == '8888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('888f888888888888888888888888888888888888888888888888888888888888'), '888888888888', 999, 1000, 64, 64, False)
assert(not success)

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('888f888888888888888888888888888888888888888888888888888888888888'), '888888888888', 999, 1000, 64, 64, True)
assert(not success)

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888f88888888888888888888888888888888888888888888888888888888'), '888888888888', 999, 1000, 64, 64, True)
assert(success)
assert(bitwork_str == '8888')

assert(calculate_expected_bitwork('888888888888', 1000, 1000, 64, 64) == '88888888')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 64, 64, False)
assert(success)
assert(bitwork_str == '88888888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888888f8888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 64, 64, False)
assert(success)
assert(bitwork_str == '88888888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888888f8888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 64, 64, True)
assert(success)
assert(bitwork_str == '88888888')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888f88888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 64, 64, True)
assert(not success)

assert(calculate_expected_bitwork('888888888888', 1000, 1000, 49, 64) == '8888888.1')
success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888888888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 49, 64, False)
assert(success)
assert(bitwork_str == '8888888.1')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888888f8888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 49, 64, False)
assert(success)
assert(bitwork_str == '8888888.1')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('88888888f8888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 49, 64, True)
assert(success)
assert(bitwork_str == '8888888.1')

success, bitwork_str = is_txid_valid_for_bitwork(hex_str_to_hash('8888888088888888888888888888888888888888888888888888888888888888'), '888888888888', 1000, 1000, 49, 64, True)
assert(not success)


0 comments on commit 84608d9

Please sign in to comment.