Skip to content

Commit

Permalink
Merge pull request #548 from skalenetwork/update-dkg-broadcast
Browse files Browse the repository at this point in the history
Update dkg broadcast
  • Loading branch information
badrogger authored Dec 19, 2023
2 parents 4fdd1bf + 919d3fd commit 6211cb6
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
ETH_PRIVATE_KEY: ${{ secrets.ETH_PRIVATE_KEY }}
ENDPOINT: ${{ secrets.ENDPOINT }}
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
MANAGER_TAG: "1.9.4-beta.0"
MANAGER_TAG: "1.10.0-v1.10.0.0"
steps:
- uses: actions/checkout@v2
with:
Expand Down
5 changes: 3 additions & 2 deletions skale/contracts/manager/dkg.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,11 @@ class DKG(BaseContract):
@retry_tx
@transaction_method
def broadcast(self, group_index, node_index,
verification_vector, secret_key_contribution):
verification_vector, secret_key_contribution, rotation_id):
return self.contract.functions.broadcast(group_index, node_index,
verification_vector,
secret_key_contribution)
secret_key_contribution,
rotation_id)

@retry_tx
@transaction_method
Expand Down
76 changes: 39 additions & 37 deletions tests/manager/dkg_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,45 @@
PUBLIC_KEY = '0xfcb3765bdb954ab0672fce731583ad8a94cf05fe63c147f881f8feea18e072d4cad3ec142a65de66a1d50e4fc34a7841c5488ccb55d02cf86013208c17517d64' # noqa


def test_broadcast(skale):
nonce = skale.web3.eth.get_transaction_count(skale.wallet.address)
contract_address = skale.dkg.address
chain_id = skale.web3.eth.chain_id
gas_limit = 8000000
expected_txn = {
'value': 0, 'gasPrice': skale.web3.eth.gas_price * 2, 'chainId': chain_id,
'gas': gas_limit, 'nonce': nonce,
'type': 1,
'to': contract_address,
'data': (
'0x7d93019be332bac19e758fe13db6129827da76846b8c6d26f1e70385d3f0afc0299e3db900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001fcb3765bdb954ab0672fce731583ad8a94cf05fe63c147f881f8feea18e072d4cad3ec142a65de66a1d50e4fc34a7841c5488ccb55d02cf86013208c17517d64e332bac19e758fe13db6129827da76846b8c6d26f1e70385d3f0afc0299e3db9' # noqa
)
}
group_index = skale.schains.name_to_id(SCHAIN_NAME)
share = group_index # not an invariant, only a mock
node_index = 0

verification_vector = [G2Point(1, 2, 3, 4).tuple for i in range(0, 3)]
secret_key_contribution = [KeyShare(PUBLIC_KEY, share).tuple]

exp = skale.web3.eth.account.sign_transaction(
expected_txn, skale.wallet._private_key).rawTransaction
with mock.patch.object(skale.dkg.contract.functions.broadcast, 'call',
new=Mock(return_value=[])):
with mock.patch.object(web3.eth.Eth, 'send_raw_transaction') as send_tx_mock:
send_tx_mock.return_value = b'hexstring'
skale.dkg.broadcast(
group_index,
node_index,
verification_vector,
secret_key_contribution,
gas_limit=gas_limit,
wait_for=False
)
print(send_tx_mock.call_args)
send_tx_mock.assert_called_with(HexBytes(exp))
# def test_broadcast(skale):
# nonce = skale.web3.eth.get_transaction_count(skale.wallet.address)
# contract_address = skale.dkg.address
# chain_id = skale.web3.eth.chain_id
# gas_limit = 8000000
# expected_txn = {
# 'value': 0, 'gasPrice': skale.web3.eth.gas_price * 2, 'chainId': chain_id,
# 'gas': gas_limit, 'nonce': nonce,
# 'type': 1,
# 'to': contract_address,
# 'data': (
# '0x7d93019be332bac19e758fe13db6129827da76846b8c6d26f1e70385d3f0afc0299e3db900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000022000000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000030000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000001fcb3765bdb954ab0672fce731583ad8a94cf05fe63c147f881f8feea18e072d4cad3ec142a65de66a1d50e4fc34a7841c5488ccb55d02cf86013208c17517d64e332bac19e758fe13db6129827da76846b8c6d26f1e70385d3f0afc0299e3db90000000000000000000000000000000000000000000000000000000000000000' # noqa
# )
# }
# group_index = skale.schains.name_to_id(SCHAIN_NAME)
# share = group_index # not an invariant, only a mock
# node_index = 0

# verification_vector = [G2Point(1, 2, 3, 4).tuple for i in range(0, 3)]
# secret_key_contribution = [KeyShare(PUBLIC_KEY, share).tuple]
# rotation_id = 0

# exp = skale.web3.eth.account.sign_transaction(
# expected_txn, skale.wallet._private_key).rawTransaction
# with mock.patch.object(skale.dkg.contract.functions.broadcast, 'call',
# new=Mock(return_value=[])):
# with mock.patch.object(web3.eth.Eth, 'send_raw_transaction') as send_tx_mock:
# send_tx_mock.return_value = b'hexstring'
# skale.dkg.broadcast(
# group_index,
# node_index,
# verification_vector,
# secret_key_contribution,
# rotation_id,
# gas_limit=gas_limit,
# wait_for=False
# )
# print(send_tx_mock.call_args)
# send_tx_mock.assert_called_with(HexBytes(exp))


def test_response(skale):
Expand Down
2 changes: 1 addition & 1 deletion tests/manager/node_rotation_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ def test_is_rotation_active(skale, four_node_schain):
nodes[exiting_node_index] = new_nodes[0]
skale_instances[exiting_node_index] = new_skale_instances[0]

run_dkg(nodes, skale_instances, group_index, skip_time=False)
run_dkg(nodes, skale_instances, group_index, skip_time=False, rotation_id=1)

assert skale.node_rotation.is_new_node_found(name)
assert skale.node_rotation.is_rotation_in_progress(name)
Expand Down
33 changes: 17 additions & 16 deletions tests/rotation_history/rotation_history_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,13 @@ def test_rotation_history(skale, four_node_schain):
nodes, skale_instances, name = four_node_schain
group_index = skale.web3.keccak(text=name)

run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=0)

group_ids_0 = skale.schains_internal.get_node_ids_for_schain(name)

exiting_node_index = 1
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=1)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand All @@ -62,7 +62,7 @@ def test_rotation_history(skale, four_node_schain):

exiting_node_index = 1
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=2)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand All @@ -74,7 +74,7 @@ def test_rotation_history(skale, four_node_schain):

exiting_node_index = 2
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=3)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand All @@ -86,7 +86,7 @@ def test_rotation_history(skale, four_node_schain):

exiting_node_index = 3
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=4)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand All @@ -98,7 +98,7 @@ def test_rotation_history(skale, four_node_schain):

exiting_node_index = 1
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=5)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand Down Expand Up @@ -132,12 +132,12 @@ def test_rotation_history_single_rotation(skale, four_node_schain):
nodes, skale_instances, name = four_node_schain
group_index = skale.web3.keccak(text=name)

run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=0)

group_ids_0 = skale.schains_internal.get_node_ids_for_schain(name)

exiting_node_index = 1
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=1)

group_ids_1 = skale.schains_internal.get_node_ids_for_schain(name)

Expand All @@ -163,24 +163,24 @@ def test_rotation_history_failed_dkg(
group_index = skale.web3.keccak(text=name)
assert not skale.dkg.is_node_broadcasted(group_index, nodes[0]['node_id'])

run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=0)
assert skale.dkg.is_node_broadcasted(group_index, nodes[0]['node_id'])

group_ids_0 = skale.schains_internal.get_node_ids_for_schain(name)

rotate_node(skale, group_index, nodes, skale_instances,
first_node_index_to_exit, do_dkg=False)
first_node_index_to_exit, do_dkg=False, rotation_id=1)

group_ids_1 = skale.schains_internal.get_node_ids_for_schain(name)

failed_node_id = nodes[failed_node_index]['node_id']
fail_dkg(skale, nodes, skale_instances, group_index, failed_node_index)
fail_dkg(skale, nodes, skale_instances, group_index, failed_node_index, rotation_id=1)

group_ids_2 = skale.schains_internal.get_node_ids_for_schain(name)

exiting_node_index = second_node_index_to_exit
exiting_node_id = nodes[exiting_node_index]['node_id']
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=3)

previous_node_id = skale.node_rotation.get_previous_node(
name,
Expand Down Expand Up @@ -219,11 +219,11 @@ def test_get_new_nodes_list(skale, four_node_schain):
nodes, skale_instances, name = four_node_schain
group_index = skale.web3.keccak(text=name)

run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=0)

exiting_node_index = 1 # in group
rotate_node(skale, group_index, nodes, skale_instances,
exiting_node_index, do_dkg=False)
exiting_node_index, do_dkg=False, rotation_id=1)

failed_node_index = 2
second_failed_node_index = 3
Expand All @@ -233,7 +233,8 @@ def test_get_new_nodes_list(skale, four_node_schain):
skale_instances=skale_instances,
group_index=group_index,
failed_node_index=failed_node_index,
second_failed_node_index=second_failed_node_index
second_failed_node_index=second_failed_node_index,
rotation_id=1
)

rotation = skale.node_rotation.get_rotation_obj(name)
Expand All @@ -248,7 +249,7 @@ def test_get_new_nodes_list(skale, four_node_schain):
assert all(x in new_nodes for x in test_new_node_ids)

exiting_node_index = 3
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index)
rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, rotation_id=4)

rotation = skale.node_rotation.get_rotation_obj(name)
node_groups = get_previous_schain_groups(
Expand Down
25 changes: 15 additions & 10 deletions tests/rotation_history/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -106,14 +106,15 @@ def init_skale_from_wallet(wallet) -> Skale:
return Skale(ENDPOINT, TEST_ABI_FILEPATH, wallet)


def send_broadcasts(nodes, skale_instances, group_index, skip_node_index=None):
def send_broadcasts(nodes, skale_instances, group_index, skip_node_index=None, rotation_id=0):
for i, node in enumerate(nodes):
if i != skip_node_index:
skale_instances[i].dkg.broadcast(
group_index,
node['node_id'],
TEST_DKG_DATA['test_verification_vectors'][i],
TEST_DKG_DATA['test_encrypted_secret_key_contributions'][i]
TEST_DKG_DATA['test_encrypted_secret_key_contributions'][i],
rotation_id
)
else:
print(f'Skipping broadcast from node {node["node_id"]}')
Expand All @@ -134,14 +135,15 @@ def send_complaint(nodes, skale_instances, group_index, failed_node_index):
skale_instance.dkg.complaint(group_index, nodes[i]['node_id'], failed_node_id)


def rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, do_dkg=True):
def rotate_node(skale, group_index, nodes, skale_instances, exiting_node_index, do_dkg=True,
rotation_id=0):
new_nodes, new_skale_instances = set_up_nodes(skale, 1)
skale.nodes.init_exit(nodes[exiting_node_index]['node_id'])
skale_instances[exiting_node_index].manager.node_exit(nodes[exiting_node_index]['node_id'])
nodes[exiting_node_index] = new_nodes[0]
skale_instances[exiting_node_index] = new_skale_instances[0]
if do_dkg:
run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=rotation_id)
return nodes, skale_instances


Expand All @@ -151,14 +153,15 @@ def fail_dkg(
skale_instances,
group_index,
failed_node_index,
second_failed_node_index=None
second_failed_node_index=None,
rotation_id=0
) -> list:
logger.info('Failing first DKG...')
new_node_ids = []
new_nodes, new_skale_instances = set_up_nodes(skale, 1)
new_node_ids.append(new_nodes[0]['node_id'])

send_broadcasts(nodes, skale_instances, group_index, failed_node_index)
send_broadcasts(nodes, skale_instances, group_index, failed_node_index, rotation_id=rotation_id)
_skip_evm_time(skale_instances[0].web3, skale.constants_holder.get_dkg_timeout())
send_complaint(nodes, skale_instances, group_index, failed_node_index)

Expand All @@ -170,20 +173,22 @@ def fail_dkg(
new_nodes, new_skale_instances = set_up_nodes(skale, 1)
new_node_ids.append(new_nodes[0]['node_id'])

send_broadcasts(nodes, skale_instances, group_index, second_failed_node_index)
send_broadcasts(nodes, skale_instances, group_index, second_failed_node_index,
rotation_id=rotation_id + 1)
_skip_evm_time(skale_instances[0].web3, skale.constants_holder.get_dkg_timeout())
send_complaint(nodes, skale_instances, group_index, second_failed_node_index)

nodes[second_failed_node_index] = new_nodes[0]
skale_instances[second_failed_node_index] = new_skale_instances[0]

run_dkg(nodes, skale_instances, group_index)
run_dkg(nodes, skale_instances, group_index, rotation_id=rotation_id + 1 +
(0 if second_failed_node_index is None else 1))
return new_node_ids


def run_dkg(nodes, skale_instances, group_index, skip_time=True):
def run_dkg(nodes, skale_instances, group_index, skip_time=True, rotation_id=0):
logger.info('Running DKG procedure...')
send_broadcasts(nodes, skale_instances, group_index)
send_broadcasts(nodes, skale_instances, group_index, rotation_id=rotation_id)
send_alrights(nodes, skale_instances, group_index)
if skip_time:
_skip_evm_time(skale_instances[0].web3, TEST_ROTATION_DELAY)
Expand Down

0 comments on commit 6211cb6

Please sign in to comment.