-
Notifications
You must be signed in to change notification settings - Fork 772
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
tx: improve tx capability handling #3010
Conversation
Codecov Report
Additional details and impacted files
Flags with carried forward coverage won't be shown. Click here to find out more. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot, looks already pretty great respectively forms to a great picture and gets us a lot closer to a modular architecture! 🤩
Some structural comments to address.
packages/tx/src/types.ts
Outdated
extends TransactionInterface<T> { | ||
readonly chainId: bigint | ||
readonly accessList: AccessListBytes | ||
readonly AccessListJSON: AccessList |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry to be a bit pedantic here, but access lists have really nothing to do with the generic introduction of typed transactions - and so with EIP2718 - and if we have this here, we still have something structurally wrong (e.g. using this type from here while we should have used the EIP2930Compatible type).
Generally this looks great though with these new interfaces! 🤩
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's true, EIP2930 capabilities should be left within their own scope, will adjust.
return keccak256(tx.getMessageToSign()) | ||
} | ||
|
||
export function serialize(tx: EIP2718CompatibleTxInterface, base?: Input): Uint8Array { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe we drop the Interface
from these names to get it a bit shorter? 🤔 No super strong preference, but we also mostly (exception: these very important reused interfaces in Common) do not explicitly name interfaces with Interface
or I
or the like in the monorepo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(but the shortening would be the greater argument here, especially if there are more arguments to follow, then this likely often moves over unnecessarily into two lines)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shortened by removing the unnecessary Interface suffix.
return concatBytes(txTypeBytes(tx.type), RLP.encode(base ?? tx.raw())) | ||
} | ||
|
||
export function validateYParity(tx: TypedTransaction) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it not possible to type with EIP2718CompatibleTxInterface
here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Forgot to adjust after refactoring, fixed.
@@ -152,6 +171,32 @@ export interface TransactionInterface<T extends TransactionType> { | |||
errorStr(): string | |||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is somewhat missing here which would complement the picture would be a LegacyTxInterface
.
I know this is likely the hardest one with eventual conflicts on re-/cross-used functionality or property access.
But did you try?
That would be great if we would/could achieve that. Since here we - again - at least to some extend replicate this old hierarchy structure which we would optimally want to completely leave behind.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. Added a LegacyTxInterface, makes this more consistent and complete.
export class FeeMarketEIP1559Transaction extends BaseTransaction<TransactionType.FeeMarketEIP1559> { | ||
export class FeeMarketEIP1559Transaction | ||
extends BaseTransaction<TransactionType.FeeMarketEIP1559> | ||
implements EIP1559CompatibleTxInterface<TransactionType.FeeMarketEIP1559> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is not structurally correct to add this implements
note respectively is both redundant and not complete at the same time. So I think we should remove.
If we would want to do this correctly/completely we would need to implement from several compatibility interfaces (here e.g. also from the EIP2930 interface), but multiple inheritance unfortunately doesn't exist in JavaScript (I thought a bit along these lines too some 1-2 years ago when thinking about how we could refactor this stuff).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I actually went back and forth on this. I agree about the point concerning multiple inheritance, but since all of the interfaces are nested within each other (eip1559 inherits from eip2930, and eip4844 inherits from eip1559), I figured this wasn't a problem. However I agree that this would not be "correct", especially if we want to treat capabilities as independent from one another.
There are no type errors even if we remove this ìmplements
(typescript automatically figures out whether or not the class fits the necessary interface when we use the Capabilities, regardless of if we explicitly mention that it implements
said interface. I'll go ahead and remove this.
@@ -306,7 +311,7 @@ export class FeeMarketEIP1559Transaction extends BaseTransaction<TransactionType | |||
* Returns the public key of the sender | |||
*/ | |||
public getSenderPublicKey(): Uint8Array { | |||
return Generic.getSenderPublicKey(this) | |||
return Legacy.getSenderPublicKey(this) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, but generally this reads super-great, to always already have the heritage of the feature read out of these calls, so that one can associate how the tx type is composed and where the functionality comes from! 🥳
export class BlobEIP4844Transaction extends BaseTransaction<TransactionType.BlobEIP4844> { | ||
export class BlobEIP4844Transaction | ||
extends BaseTransaction<TransactionType.BlobEIP4844> | ||
implements EIP4844CompatibleTxInterface<TransactionType.BlobEIP4844> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here again (and for the other tx types too), I think we should remove.
This blurs again the capability concept.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
removed
Everything should be addressed @holgerd77, can be re-reviewed! :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot, this looks really fantastic 😍, I didn't imagine this to turn out SO structurally clean on all fronts, totally love this! 🤩
Will merge.
This PR addresses comments and suggestions for improvements that were made on #2993