Skip to content
This repository has been archived by the owner on Nov 15, 2023. It is now read-only.

signed wrapper #1283

Merged
merged 15 commits into from
Jun 20, 2020
Merged

signed wrapper #1283

merged 15 commits into from
Jun 20, 2020

Conversation

coriolinus
Copy link
Contributor

Closes #1282.

Extracts signing behavior from concrete types into a wrapper where the behavior can be written exactly once.

This is strictly an addition as of this commit; nothing is yet
changed in existing behavior.
@github-actions github-actions bot added the A3-in_progress Pull request is in progress. No review needed at this stage. label Jun 18, 2020
Copy link
Contributor Author

@coriolinus coriolinus left a comment

Choose a reason for hiding this comment

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

@rphmeier if you have time, I'd appreciate an early look at this to ensure that this is the right direction to take this.

Next up: replace SignedStatement, SignedAvailabilityBitfield with the typedefs from the guide and ensure everything still builds.

node/primitives/src/lib.rs Outdated Show resolved Hide resolved
node/primitives/src/lib.rs Outdated Show resolved Hide resolved
node/primitives/src/lib.rs Outdated Show resolved Hide resolved
@coriolinus coriolinus self-assigned this Jun 18, 2020
// because there's no blanket impl of `AsRef<T> for T`. In the end, we just invent our
// own trait which does what we need: EncodeAs.
impl<Payload: EncodeAs<RealPayload>, RealPayload: Encode> Signed<Payload, RealPayload> {
fn payload_data(payload: &Payload, context: SigningContext) -> Vec<u8> {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not really a fan of inherent impls that aren't constructors TBH

Copy link
Contributor

@rphmeier rphmeier Jun 18, 2020

Choose a reason for hiding this comment

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

Not sure if this is considered bad practice, but my intuition is that it generally is, although I don't know what resource to reference on that

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The reason this is an inherent impl is that it's used within the constructor. Users shouldn't care; it's private.

// the payload, and we don't want that. We can't bound it on `Payload: AsRef<RealPayload>`
// because there's no blanket impl of `AsRef<T> for T`. In the end, we just invent our
// own trait which does what we need: EncodeAs.
impl<Payload: EncodeAs<RealPayload>, RealPayload: Encode> Signed<Payload, RealPayload> {
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems like the EncodeAs machinery could be replaced with a simple From bound, but actually not, because you'd have to do some cloning internally for types like AvailabilityBitfield.

Playground to avoid this: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f734b13e93d6a7baa8b19dab78df345f

But it gets a bit messy

Copy link
Contributor

Choose a reason for hiding this comment

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

You have to use the trait because you would need HKT to do this with pure closures.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Exactly right on the reason we're using EncodeAs instead of From/Into.

I think we may have been overthinking the solution, though; my new attempt is in 234eca5.

This isn't an ideal solution, because it depends on the
implementation details of how SCALE encodes tuples, but OTOH
that behavior seems unlikely to change anytime soon.
@coriolinus coriolinus added B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders. labels Jun 19, 2020
@coriolinus coriolinus marked this pull request as ready for review June 19, 2020 09:55
@coriolinus coriolinus added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Jun 19, 2020
@coriolinus coriolinus requested a review from rphmeier June 19, 2020 09:57
Not sure why cargo check didn't catch this earlier; oh well.
@rphmeier rphmeier added A8-mergeoncegreen and removed A0-please_review Pull request needs code review. labels Jun 19, 2020
}
}
}
pub type SignedStatement = Signed<Statement, CompactStatement>;
Copy link
Contributor

Choose a reason for hiding this comment

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

We need to be careful that runtime APIs accept Signed<CompactStatement>, not Signed<Statement>.

I propose calling this SignedFullStatement

@rphmeier
Copy link
Contributor

@coriolinus I submitted 75ce529 to fix tests and create a clear type boundary between signed statements and their "full" counterparts. I also merged with master in an effort to get CI to pass. Please merge if my changes are acceptable

@coriolinus
Copy link
Contributor Author

Happy to merge once green! Really not sure what's going on with CI; I was wrestling with that all afternoon yesterday, with no success.

75ce529 seems fine to me, but it looks like we only ever use SignedFullStatements. When would we produce/use a (new definition) SignedStatement? It mentions sending it to the chain, but I don't know under what circumstances we'd want to do that.

One nice property: we could impl From<SignedFullStatement> for SignedStatement very cheaply, because the actual signature won't change. Not sure if we actually need that, but it would work.

@rphmeier
Copy link
Contributor

When would we produce/use a (new definition) SignedStatement? It mentions sending it to the chain, but I don't know under what circumstances we'd want to do that.

Yeah, we don't do that now, but I'd imagine we will use it in the dispute-resolution process. The Validity module will track the candidate hash for all candidates within the acceptance period, and it'll accept SignedStatements from validators. Unlike the backing phase, we want to accept any of Valid, Seconded, and Invalid statements, although for secondary approval checkers it'll be disallowed to include Seconded statements. But for validators whose Seconded statement might have been missed in the backing phase, we'd want those to be includable after the fact.

@rphmeier rphmeier merged commit 4f79b77 into master Jun 20, 2020
@rphmeier rphmeier deleted the prgn-signed-wrapper branch June 20, 2020 18:56
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
B0-silent Changes should not be mentioned in any release notes C1-low PR touches the given topic and has a low impact on builders.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Extract Signed<T> to replace SignedStatement, SignedBitfield, etc
3 participants