Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unable to create as_multi calls due to encoding rules of OpaqueCall's #20

Open
CodeForcer opened this issue Jul 27, 2020 · 2 comments
Open

Comments

@CodeForcer
Copy link
Contributor

Currently the encoding rules for as_multi require the call to be serialised:

as_multi = ScaleDecoder.get_decoder_class("Call", metadata=kusama.metadata)
transfer = ScaleDecoder.get_decoder_class("OpaqueCall", metadata=kusama.metadata)
transfer.encode(
    {
        "call_module": "Balances",
        "call_function": "transfer",
        "call_args": {"dest": "CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V", "value": 10000000000000},
    }
)
as_multi.encode(
    {
        "call_module": "Multisig",
        "call_function": "as_multi",
        "call_args": {
            "call": str(transfer),
            "maybe_timepoint": {"height": 3012294, "index": 3},
            "other_signatories": sorted(['D2bHQwFcQj11SvtkjULEdKhK4WAeP6MThXgosMHjW9DrmbE', 'CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V']),
            "threshold": 2,
            "store_call": True,
            "max_weight": 10,
        },
    }
)

However, presumably due to a metadata change, the same parameter is now only accepted in dictionary format:

  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/ksmutils/helper.py", line 161, in as_multi_signature_payload
    as_multi.encode(
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1180, in process_encode
    data += arg_obj.encode(param_value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1188, in process_encode
    return super().process_encode(str(call_obj.encode(value)))
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1157, in process_encode
    if call_module.name == value['call_module'] and call_function.name == value['call_function']:
TypeError: string indices must be integers
FAILED

I submitted a PR with one patch for the error, but ideally this could be handled at the point of as_multi encoding

@arjanz
Copy link
Member

arjanz commented Jul 27, 2020

There is a special OpaqueCall class that takes a dict as input for encoding and internally wraps the output so it is in fact a Bytes:

def process_encode(self, value):

So basically, all you have to do is rewrite your as_multi to:

as_multi = ScaleDecoder.get_decoder_class("Call", metadata=self.metadata_decoder)

as_multi.encode(
    {
        "call_module": "Multisig",
        "call_function": "as_multi",
        "call_args": {
            "call": {
                "call_module": "Balances",
                "call_function": "transfer",
                "call_args": {"dest": "CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V", "value": 10000000000000},
            },
            "maybe_timepoint": {"height": 3012294, "index": 3},
            "other_signatories": sorted(['D2bHQwFcQj11SvtkjULEdKhK4WAeP6MThXgosMHjW9DrmbE',
                                         'CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V']),
            "threshold": 2,
            "store_call": True,
            "max_weight": 10,
        },
    }
)

@Shawncomst
Copy link

Currently the encoding rules for as_multi require the call to be serialised:

as_multi = ScaleDecoder.get_decoder_class("Call", metadata=kusama.metadata)
transfer = ScaleDecoder.get_decoder_class("OpaqueCall", metadata=kusama.metadata)
transfer.encode(
    {
        "call_module": "Balances",
        "call_function": "transfer",
        "call_args": {"dest": "CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V", "value": 10000000000000},
    }
)
as_multi.encode(
    {
        "call_module": "Multisig",
        "call_function": "as_multi",
        "call_args": {
            "call": str(transfer),
            "maybe_timepoint": {"height": 3012294, "index": 3},
            "other_signatories": sorted(['D2bHQwFcQj11SvtkjULEdKhK4WAeP6MThXgosMHjW9DrmbE', 'CofvaLbP3m8PLeNRQmLVPWmTT7jGgAXTwyT69k2wkfPxJ9V']),
            "threshold": 2,
            "store_call": True,
            "max_weight": 10,
        },
    }
)

However, presumably due to a metadata change, the same parameter is now only accepted in dictionary format:

  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/ksmutils/helper.py", line 161, in as_multi_signature_payload
    as_multi.encode(
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1180, in process_encode
    data += arg_obj.encode(param_value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1188, in process_encode
    return super().process_encode(str(call_obj.encode(value)))
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/base.py", line 298, in encode
    self.data = self.process_encode(value)
  File "/Users/nathan/.pyenv/versions/3.8.1/envs/ksmapi/lib/python3.8/site-packages/scalecodec/types.py", line 1157, in process_encode
    if call_module.name == value['call_module'] and call_function.name == value['call_function']:
TypeError: string indices must be integers
FAILED

38.975
I submitted a PR with one patch for the error, but ideally this could be handled at the point of as_multi encoding

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants