Skip to content

Commit

Permalink
fix: multi sign signatures & fees (#143)
Browse files Browse the repository at this point in the history
  • Loading branch information
alexbarnsley authored Aug 22, 2024
1 parent 63e828a commit 0a0f2ef
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 8 deletions.
4 changes: 2 additions & 2 deletions crypto/transactions/builder/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,10 @@ def multi_sign(self, passphrase, index):

msg = self.transaction.to_bytes()
secret = unhexlify(PrivateKey.from_passphrase(passphrase).to_hex())
signature = hexlify(Signature.sign(msg, secret).encode())
signature = Signature.sign(msg, secret)

index_formatted = hex(index).replace('x', '')
self.transaction.signatures.append(index_formatted + signature.decode())
self.transaction.signatures.append(index_formatted + signature)

def serialize(self, skip_signature=False, skip_second_signature=False, skip_multi_signature=False):
"""Perform AIP11 compliant serialization.
Expand Down
6 changes: 1 addition & 5 deletions crypto/transactions/builder/multi_signature_registration.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,8 @@ def set_min(self, minimum_participants):

def set_public_keys(self, public_keys):
self.transaction.asset['multiSignature']['publicKeys'] = public_keys
self.transaction.fee = (len(public_keys) + 1) * self.transaction.fee

def add_participant(self, public_key: str):
self.transaction.asset['multiSignature']['publicKeys'].append(public_key)

public_key_count = (len(self.transaction.asset['multiSignature']['publicKeys']) + 1)
transaction_fee = get_fee(TRANSACTION_MULTI_SIGNATURE_REGISTRATION)

self.transaction.fee = public_key_count * transaction_fee
self.transaction.fee = get_fee(TRANSACTION_MULTI_SIGNATURE_REGISTRATION)
6 changes: 6 additions & 0 deletions tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import pytest


@pytest.fixture
def passphrase():
"""Passphrase used for tests"""

return 'my super secret passphrase'

@pytest.fixture
def transaction_type_0():
"""Transaction of type "transfer"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ def test_multi_signature_registration_transaction(passphrase):

assert transaction_dict['nonce'] == 1
assert transaction_dict['version'] == 1
assert transaction_dict['fee'] == 2000000000
assert transaction_dict['fee'] == 500000000
assert transaction_dict['signature']
assert transaction_dict['type'] is TRANSACTION_MULTI_SIGNATURE_REGISTRATION
assert transaction_dict['typeGroup'] == TRANSACTION_TYPE_GROUP.CORE.value
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
from crypto.constants import TRANSACTION_FEES
from crypto.identity.public_key import PublicKey
from crypto.transactions.builder.multi_signature_registration import MultiSignatureRegistration
from crypto.transactions.deserializer import Deserializer
from crypto.transactions.serializer import Serializer


def test_multi_signature_registration_deserializer(transaction_type_4):
Expand All @@ -21,3 +25,76 @@ def test_multi_signature_registration_deserializer(transaction_type_4):
assert actual.signatures == transaction_type_4['signatures']

actual.verify_multisig_schnorr()


def test_multi_signature_registration_deserializer_from_serialized(transaction_type_4):
result = Serializer(transaction_type_4).serialize(False, True, False)

deserializer = Deserializer(result)
actual = deserializer.deserialize()

assert actual.version == transaction_type_4['version']
assert actual.network == transaction_type_4['network']
assert actual.typeGroup == transaction_type_4['typeGroup']
assert actual.type == transaction_type_4['type']
assert actual.nonce == transaction_type_4['nonce']
assert actual.senderPublicKey == transaction_type_4['senderPublicKey']
assert actual.fee == transaction_type_4['fee']
assert actual.amount == transaction_type_4['amount']
assert actual.signature == transaction_type_4['signature']
assert actual.id == transaction_type_4['id']

assert actual.asset['multiSignature']['min'] == transaction_type_4['asset']['multiSignature']['min']
assert actual.asset['multiSignature']['publicKeys'] == transaction_type_4['asset']['multiSignature']['publicKeys']
assert actual.signatures == transaction_type_4['signatures']

actual.verify_multisig_schnorr()

def test_with_methods(passphrase):
transaction = MultiSignatureRegistration()

passphrase_2 = f'{passphrase} 2'
passphrase_3 = f'{passphrase} 3'

sender_public_key = PublicKey.from_passphrase(passphrase)
participant_2 = PublicKey.from_passphrase(passphrase_2)
participant_3 = PublicKey.from_passphrase(passphrase_3)

transaction.set_sender_public_key(sender_public_key)
transaction.set_nonce(15)
transaction.set_min(2)
transaction.add_participant(sender_public_key)
transaction.add_participant(participant_2)
transaction.add_participant(participant_3)

transaction.multi_sign(passphrase, 0)
transaction.multi_sign(passphrase_2, 1)
transaction.multi_sign(passphrase_3, 2)

transaction.sign(passphrase)

result = Serializer(transaction.to_dict()).serialize(False, True, False)

deserializer = Deserializer(result)
actual = deserializer.deserialize()

assert actual.version == 1
assert actual.network == 30
assert actual.typeGroup == 1
assert actual.type == 4
assert actual.nonce == 15
assert actual.senderPublicKey == sender_public_key
assert actual.fee == TRANSACTION_FEES[4]
assert actual.amount == 0
assert actual.signature == transaction.transaction.signature
assert actual.id == transaction.transaction.id

assert actual.asset['multiSignature']['min'] == 2
assert actual.asset['multiSignature']['publicKeys'][0] == sender_public_key
assert actual.asset['multiSignature']['publicKeys'][1] == participant_2
assert actual.asset['multiSignature']['publicKeys'][2] == participant_3

assert actual.signatures == transaction.transaction.signatures
assert len(actual.signatures) == 3

actual.verify_multisig_schnorr()

0 comments on commit 0a0f2ef

Please sign in to comment.