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

V14 Decoding #45

Merged
merged 55 commits into from
Oct 19, 2021
Merged

V14 Decoding #45

merged 55 commits into from
Oct 19, 2021

Conversation

jsdw
Copy link
Collaborator

@jsdw jsdw commented Oct 11, 2021

This PR lays the foundation for decoding using V14 metadata.

Currently supported is decoding (v4) extrinsics (multiple or single) based on V14 metadata. Decoding other things to follow in subsequent work.

Copy link
Contributor

@dvdplm dvdplm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Went through this commit by commit, so many of my comments are likely irrelevant. It reads like a good coming-of-age novel, with SubstrateType as the tragic hero!

@@ -0,0 +1,18 @@
[package]
name = "core_v14"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might not be the best name if this crate could one day be used on its own? desub-metadata-v14?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely; the plan is to merge it with a crap name, and then do a PR to rename soem crates.. probably promoting this in place of the <=V13 logic, and moving that logic to be under something with legacy in the name (we'll need to work out the naming though when we get to that!)

core_v14/src/generic_extrinsic.rs Outdated Show resolved Hide resolved
core_v14/src/substrate_value/data.rs Outdated Show resolved Hide resolved
core_v14/src/substrate_value/substrate_value.rs Outdated Show resolved Hide resolved
core_v14/src/substrate_value/substrate_value.rs Outdated Show resolved Hide resolved
core_v14/src/decoder/utils.rs Outdated Show resolved Hide resolved
Tuple(TupleType),
Primitive(PrimitiveType),
Compact(CompactType),
BitSequence(BitSequenceType),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this one feature gated in scale-info?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is! Honestly I've no idea whether or not it's necessary in the decoding, but the <=V13 logic handled decoding to bitvec, so I did too. I did more recently run into some sporadic errors that meant I had to add a feature flag, though...

core_v14/src/substrate_type.rs Outdated Show resolved Hide resolved
core_v14/src/metadata/mod.rs Outdated Show resolved Hide resolved
Comment on lines 22 to 24
CannotFindCall(u8, u8),
#[error("Failed to decode extrinsic: {0}")]
CannotFindType(#[from] MetadataError),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe s/Cannot/Unknown/?

@dvdplm
Copy link
Contributor

dvdplm commented Oct 15, 2021

GenericExtrinsic to Extrinsic would be good too

I second this. "Extrinsic" was chosen very carefully to reflect its "anything really, as long as it comes from the outside"-nature, so piling on "generic" on top of it doesn't add much, semantically.

@jsdw
Copy link
Collaborator Author

jsdw commented Oct 15, 2021

GenericExtrinsic to Extrinsic sounds good to me! Definitely a good time to ponder names and make sure we're happy with them :)

@jsdw jsdw marked this pull request as ready for review October 15, 2021 12:16
@jsdw jsdw changed the title [WIP] V14 Decoding V14 Decoding Oct 15, 2021

impl<'a> AllExtrinsicBytes<'a> {
/// How many extrinsics are there? Note that this is simply the reported number of extrinsics,
/// and if the extrinsic bytes are malformed, it may not equal the actual number of extrinsics
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you elaborate on "extrinsic bytes are malformed"?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure! The length is calculated assuming that you've passing a scale encoded version of Vec<Vec<u8>> (so we have the vector length and then the bytes for each extrinsic also have a length prefixed).

But the actual iteration doesn't rely on that reported length (it can't, really), so it may be that we run out of bytes before we've actually decoded as many extrinsics as the length reported we'd have.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(In general, I've tried to make sure that this iterator won't panic even if you give completely nonsense bytes, but that hasn't been thoroughly vetted!)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so it may be that we run out of bytes before we've actually decoded as many extrinsics as the length reported we'd have.

Ahh, this puts it together for me, that clears up some confusion I was having when reading through the impl<'a> Iterator.

Thanks for the explanation

.gitignore Outdated Show resolved Hide resolved

```rust
use hex;
use core_v14::{ Metadata, Decoder };
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the name of the crate changes, just a reminder that this would update as well, based on the comment above?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeahh, the name is almost certain to change, but at least it should break this example and make it obvious that we need to fix it (I should probably confirm that CI is checking the examples..) :)

core_v14/src/decoder/decode_type.rs Outdated Show resolved Hide resolved
core_v14/src/decoder/decode_type.rs Outdated Show resolved Hide resolved
core_v14/src/decoder/mod.rs Outdated Show resolved Hide resolved
}

/// Get the decoded metadata version. At some point `RuntimeMetadataPrefixed` will end up
/// with a `.version()` method to return the version, and then this can be removed.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make an issue for this so we don't forget

core_v14/src/metadata/mod.rs Outdated Show resolved Hide resolved
core_v14/src/metadata/mod.rs Outdated Show resolved Hide resolved
let val = match ty {
TypeDefPrimitive::Bool => Primitive::Bool(bool::decode(data)?),
TypeDefPrimitive::Char => {
// [jsdw] TODO: There isn't a `char::decode`. Why? Is it wrong to use u32 or is there a more "proper" way?
Copy link
Contributor

@insipx insipx Oct 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

https://docs.substrate.io/v3/advanced/scale-codec/

Strings are just encoded as an array of u8 so it is possible there is no notion of char. I'm guessing this is something that scale-info added but which is not present in scale-codec

Copy link
Collaborator Author

@jsdw jsdw Oct 18, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems that way; I want to handle the scale info type properly, but since scale-codec isn't implemented for char I'm not actually sure what the expectation is (so I'm just assuming that char will be a 32bit value like in Rust!)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that make sense, i think that's the most sensible route

_ty: &TypeDefBitSequence<PortableForm>,
_types: &PortableRegistry,
) -> Result<BitSequence, DecodeTypeError> {
// [jsdw] TODO: might be worth checking the bit_store and bit_order types
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think the Lsb0/u8 is definition in polkadot-related runtimes, but i parity-scale codec impl Decode/Encode directly on O/T generics. Not sure any other project is using anything other than u8/lsb0, and it might significantly complicate bitsequence decoding if we were to make it generic?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah; I can see that fairly arbitrary ordering and storage format choices could be made which might be somewhat hard to handle! Offhand it looks like scale-codec just encodes it as the number of bits and then a slice of whatever the underlying storage type is. I think that means that whatever we assume we'll at least decode the correct number of bits, even if we mess up the ordering of them.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(as a random side note: when encoding the bitvec type via serde, an additional piece of information is encoded (which may describe format details), It might be that the way scale-codec encodes/decodes it means that it must always be a u8 backed lsb0 ordered thing)

jsdw and others added 2 commits October 18, 2021 09:30
Copy link
Contributor

@insipx insipx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bar clippy lints this lgtm

Copy link
Member

@TarikGul TarikGul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

took a few days to read thorugh, but lgtm! Great Job!

@jsdw
Copy link
Collaborator Author

jsdw commented Oct 19, 2021

@insipx The clippy lints are txdecoder related I think; what's the best way to handle this? If you've been working on an update for it, should we merge the update into this PR, or should we merge this PR in full knowledge that it has these errors and then your work can be merged on top to fix them, orrr should we just exclude the txdecoder bin again in this PR so that the related errors go away (like how it was)? :)

@insipx
Copy link
Contributor

insipx commented Oct 19, 2021

Ah sorry somehow I saw the clippy lints and forgot about that (i think in my head I confused clippy lints with the compile errors from before)

Anyway we can just merge this then, I'll just fix the clippy lints in the txdecoder branch before merging that, since I have to change the core14 ref anyway

@insipx insipx merged commit 7f3e4b2 into master Oct 19, 2021
@jsdw jsdw deleted the jsdw-desub-new-v14 branch October 20, 2021 07:51
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

Successfully merging this pull request may close these issues.

4 participants