Skip to content

Commit

Permalink
Merge pull request #355 from golemfactory/prevent-testnet-to-mainnet-…
Browse files Browse the repository at this point in the history
…replay

require the GNTDeposit contract address in signatures to mitigate mai…
  • Loading branch information
shadeofblue authored Aug 20, 2019
2 parents 2cf659b + 4bbe19b commit f22a1af
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 17 deletions.
10 changes: 7 additions & 3 deletions golem_messages/datastructures/promissory.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,23 +36,26 @@ class PromissoryNote:
promissory note has been issued
"""
def __init__(
def __init__( # pylint: disable=too-many-arguments
self,
address_from: str,
address_to: str,
amount: int,
subtask_id: str,
contract_address: str,
):
self.address_from = address_from
self.address_to = address_to
self.amount = amount
self.subtask_id = subtask_id
self.contract_address = contract_address

def __repr__(self):
return (
f"<{self.__class__.__name__}: "
f" from: {self.address_from}, to: {self.address_to}, "
f"amount: {self.amount}, subtask_id: {self.subtask_id}>"
f"amount: {self.amount}, subtask_id: {self.subtask_id}, "
f"contract: {self.contract_address}>"
)

@property
Expand All @@ -62,6 +65,7 @@ def subtask_id_bytes(self):
@property
def hexmsg(self) -> str:
return "0x" + \
self.contract_address[2:] + \
self.address_from[2:] + \
self.address_to[2:] + \
self.amount.to_bytes(32, byteorder='big').hex() + \
Expand Down Expand Up @@ -140,5 +144,5 @@ def verify_concent_promissory_note(
return self._get_concent_promissory_note(
deposit_contract_address
).sig_valid(
self.concent_promissory_note_sig
getattr(self, self.CONCENT_PROMISSORY_NOTE_SIG)
)
1 change: 1 addition & 0 deletions golem_messages/message/concents.py
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ def _get_concent_promissory_note(
address_to=deposit_contract_address,
amount=ttc.price,
subtask_id=ttc.subtask_id,
contract_address=deposit_contract_address,
)


Expand Down
40 changes: 36 additions & 4 deletions golem_messages/message/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,14 @@ def validate_ownership(self, concent_public_key=None):
)
return super().validate_ownership(concent_public_key)

def _get_promissory_note(self) -> promissory.PromissoryNote:
def _get_promissory_note(
self, deposit_contract_address: str) -> PromissoryNote:
return promissory.PromissoryNote(
address_from=self.requestor_ethereum_address,
address_to=self.provider_ethereum_address,
amount=self.price,
subtask_id=self.subtask_id,
contract_address=deposit_contract_address,
)

def _get_concent_promissory_note(
Expand All @@ -450,16 +452,46 @@ def _get_concent_promissory_note(
address_to=deposit_contract_address,
amount=self.price,
subtask_id=self.subtask_id,
contract_address=deposit_contract_address,
)

def sign_promissory_note(self, private_key: bytes) -> None:
def sign_promissory_note(
self,
deposit_contract_address: str,
private_key: bytes
) -> None:
self.promissory_note_sig = self._get_promissory_note( # noqa pylint: disable=attribute-defined-outside-init
deposit_contract_address=deposit_contract_address
).sign(
privkey=private_key
)

def verify_promissory_note(self) -> bool:
return self._get_promissory_note().sig_valid(self.promissory_note_sig)
def verify_promissory_note(self, deposit_contract_address: str) -> bool:
return self._get_promissory_note(
deposit_contract_address=deposit_contract_address
).sig_valid(self.promissory_note_sig)

def sign_all_promissory_notes(
self,
deposit_contract_address: str,
private_key: bytes
) -> None:
self.sign_concent_promissory_note(
deposit_contract_address=deposit_contract_address,
private_key=private_key,
)
self.sign_promissory_note(
deposit_contract_address=deposit_contract_address,
private_key=private_key,
)

def verify_all_promissory_notes(
self, deposit_contract_address: str) -> bool:
return self.verify_concent_promissory_note(
deposit_contract_address=deposit_contract_address,
) and self.verify_promissory_note(
deposit_contract_address=deposit_contract_address
)


@library.register(TASK_MSG_BASE + 3)
Expand Down
14 changes: 9 additions & 5 deletions tests/datastructures/test_promissory.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ def setUp(self) -> None:
b'\xa1\x02\xf7\x06\x0c\x05\xa0\xbb\xbd\xbd\xa5\xfc\x9e' \
b'\x8a_%{ \xbd\x12\xe5\r\xdb(6\x8e\x9f'

# an arbitrary `to` and `amount`
# an arbitrary `to`, `amount` and `contract_address`
self.address_to = '0x8bbd87311EA35490B6BE9c7C81e2ae5BCD6f111D'
self.amount = 667
self.contract_address = '0x89915ddA14eFd6b064da953431E8b7f902d89c83'

# and not so arbitrary `subtask_id` + bytes
self.subtask_id = '84ef2787-9daa-abad-0a0b-77b35dc3a290'
Expand All @@ -40,6 +41,7 @@ def promissory_note(self):
address_to=self.address_to,
amount=self.amount,
subtask_id=self.subtask_id,
contract_address=self.contract_address,
)

def test_subtask_id_bytes(self):
Expand All @@ -49,8 +51,9 @@ def test_subtask_id_bytes(self):
)

def test_hexmsg(self):
# address_from + address_to + amount + subtask_id
# contract_address + address_from + address_to + amount + subtask_id
hexmsg = '0x'\
'89915ddA14eFd6b064da953431E8b7f902d89c83' \
'459bC6422378156c3dbf3d7Ad4ec3411BA488f40' \
'8bbd87311EA35490B6BE9c7C81e2ae5BCD6f111D' \
'00000000000000000000000000000000' \
Expand All @@ -60,8 +63,8 @@ def test_hexmsg(self):
self.assertEqual(self.promissory_note.hexmsg, hexmsg)

def test_hash(self):
pn_hash = b'\xf2Co>E\x1b9)a\x92-\xc8\xd2\x1b0S' \
b'\xbe\xc3\\1\xe5!(\xc6~K\xd3\x1f]\xd7Te'
pn_hash = b'\xa97\xd5\xfb\x0f\x18\x9d9m\x9f\xa9U\x87\xec:\xe8' \
b'=\x86WMc\x98\xe3\x08\xdf\xee\xa9\x05x\x98`\xbd'
self.assertEqual(self.promissory_note.hash, pn_hash)

def test_sign(self):
Expand All @@ -80,7 +83,8 @@ def test_not_sig_valid_broken_content(self):
address_from=self.address_from,
address_to=self.address_from, # purposefully broken
amount=self.amount,
subtask_id=self.subtask_id
subtask_id=self.subtask_id,
contract_address=self.contract_address,
).sign(
self.privkey
)
Expand Down
30 changes: 25 additions & 5 deletions tests/message/tasks/test_task_to_compute.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,10 @@ def test_promissory_note(self):
ttc: message.tasks.TaskToCompute = self.FACTORY(
ethsig__keys=requestor_keys
)
ttc.sign_promissory_note(private_key=requestor_keys.raw_privkey)
ttc.sign_promissory_note(
self.gntdeposit,
private_key=requestor_keys.raw_privkey
)

self.assertIsInstance(
ttc.promissory_note_sig,
Expand All @@ -197,18 +200,21 @@ def test_promissory_note(self):
)

self.assertTrue(
ttc2.verify_promissory_note(),
ttc2.verify_promissory_note(self.gntdeposit),
)

def test_promissory_note_empty(self):
self.assertFalse(
self.msg.verify_promissory_note()
self.msg.verify_promissory_note(self.gntdeposit)
)

def test_promissory_note_bad(self):
requestor_keys = cryptography.ECCx(None)
self.msg.sign_promissory_note(private_key=requestor_keys.raw_privkey)
self.assertFalse(self.msg.verify_promissory_note())
self.msg.sign_promissory_note(
self.gntdeposit,
private_key=requestor_keys.raw_privkey
)
self.assertFalse(self.msg.verify_promissory_note(self.gntdeposit))

def test_concent_promissory_note(self):
requestor_keys = cryptography.ECCx(None)
Expand Down Expand Up @@ -240,6 +246,20 @@ def test_concent_promissory_note(self):
ttc2.verify_concent_promissory_note(self.gntdeposit),
)

def test_sign_all_promissory_notes(self):
requestor_keys = cryptography.ECCx(None)
ttc: message.tasks.TaskToCompute = self.FACTORY(
ethsig__keys=requestor_keys
)
ttc.sign_all_promissory_notes(
self.gntdeposit,
private_key=requestor_keys.raw_privkey
)
ttc2: message.tasks.TaskToCompute = helpers.dump_and_load(ttc)
self.assertTrue(
ttc2.verify_all_promissory_notes(self.gntdeposit)
)


class TaskToComputeSignedChainFactory(unittest.TestCase):
def test_factory_with_signed_nested_messages(self):
Expand Down

0 comments on commit f22a1af

Please sign in to comment.