iotaledger / iota.py

PyOTA: The IOTA Python API Library
https://docs.iota.org/
MIT License
344 stars 124 forks source link

Multisig bundle validation fails when digests generated with security_level < 3 #276

Open woywoy123 opened 4 years ago

woywoy123 commented 4 years ago
#User 1
api_1 = MultisigIota(adapter=Node,seed=Seed(u1), local_pow = True)
gd_result = api_1.get_digests(index=1,count=1, security_level=2)
digest_1 = gd_result['digests'][0]  # type: Digest

#User 2
api_2 = MultisigIota(adapter=Node,seed=Seed(u2), local_pow = True)
gd_result = api_2.get_digests(index=3, count=1, security_level=1)
digest_2 = gd_result['digests'][0]

#User 3
api_3 = MultisigIota(adapter=Node,seed=Seed(u3), local_pow = True)
gd_result = api_3.get_digests(index=3, count=1, security_level=1)
digest_3 = gd_result['digests'][0]

#Creating the multisig address
cma_result = api_1.create_multisig_address(digests=[digest_2, digest_3])
multisig_address = cma_result['address']  # type: MultisigAddress
print(multisig_address.with_valid_checksum())

#Proposing the multisignature 
pmt_result = api_2.prepare_multisig_transfer(transfers=[ProposedTransaction(address=Address(Receiver),value=1)], multisig_input=multisig_address, change_address=Receiver)
prepared_trytes = pmt_result['trytes']
bundle = Bundle.from_tryte_strings(prepared_trytes)

gpk_result = api_2.get_private_keys(index=3, count=1, security_level=1)
private_key_2 = gpk_result['keys'][0]  # type: PrivateKey
private_key_2.sign_input_transactions(bundle, 1)

gpk_result = api_3.get_private_keys(index=3, count=1, security_level=1)
private_key_3 = gpk_result['keys'][0]  # type: PrivateKey
private_key_3.sign_input_transactions(bundle, 2)

signed_trytes = bundle.as_tryte_strings()

validator = BundleValidator(bundle)
if not validator.is_valid():
    print("Failed")

The code above is a slight modification of [1], when you set the security levels and the digests exactly like in [1] this code will work. But when you generate a multisignature address from only 2 digests with security level 1 on each this wont work. Anyone come across this issue?

[1]. https://github.com/iotaledger/iota.py/blob/develop/examples/multisig.py

lzpap commented 4 years ago

hey @woywoy123 I tried the original example with security_level 1 and 2, they both fail bundle validation with signature error, however with security_level=3 everything is great. I'll have to investigate for the root cause more as I'm not yet familiar with multisigs. Maybe @todofixthis has a better understanding of multisigs in PyOTA?

woywoy123 commented 4 years ago

@lzpap glad to hear that this is actually a valid bug. Does this also occur with the java implementation?

lzpap commented 4 years ago

@kwek20 any idea about the java multisig implementation?

@woywoy123 it might also be that the bug is in the python lib bundle validator, not in the way PyOTA handles multisigs.

kwek20 commented 4 years ago

We have this one as an example: https://github.com/iotaledger/iota-java/blob/dev/jota/src/test/java/org/iota/jota/IotaMultisigTest.java

I just tested it for multisig with sec 2, 1 and 1, and it doesnt work, but for a different reason :D Ive never tested it for sec != 3 :o

Ill investigate and let you know @lzpap

woywoy123 commented 4 years ago

I think I may have found another bug in the multisignature segment. When I try to add in multiple beneficiaries in a Tx it works (sec=3) but I cant specify individual token value transfers. To make this clearer; I have 3 beneficiaries: A1, A2, A3 I want to pay; A1(2i), A2(3i), A3(4i) But when I try to include value parameters I cant add more than 1 value at a time. :P

todofixthis commented 4 years ago

Hi @woywoy123 could you log the above as a separate issue?