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

Breaking up the Transaction class #709

Closed
s1na opened this issue May 10, 2019 · 8 comments
Closed

Breaking up the Transaction class #709

s1na opened this issue May 10, 2019 · 8 comments

Comments

@s1na
Copy link
Contributor

s1na commented May 10, 2019

Created this issue to continue the discussion started in ethereumjs/ethereumjs-tx#142 and to garner feedback whether you think this'd make sense. Here's a rough sketch of one (non-breaking) approach that comes to my mind:

Make TxData a class, and use it to store the actual data for the transaction, plus methods for serialization/deserialization. In Transaction's constructor instantiate TxData and store it for later use (possibly add a static fromTxData method). Logic methods stay on Transaction and use TxData as source of data but do not mutate it.

If this is too vague I can try to write up (or a diagram) of something more concrete. Please feel free to propose other ideas.

@alcuadrado
Copy link
Member

alcuadrado commented May 10, 2019

I see the issues in ethereumjs/ethereumjs-tx#140 and ethereumjs/ethereumjs-tx#150 related to this one, and that's why I proposed moving those conversations here.

IMO the problems we are seeing come from a few design desitions:

  1. The internal representation of the transaction values is completely coupled to RLP. This leads to confusing things, like leading 0s being removed unexpectedly.

  2. Unsigned transactions have bogus signatures. This is confusing both as a developer of the lib and as a user of it, for example tx.hash(false) is weird.

  3. Many operations mutate the internal state and these side effects are used internally in unexpected ways. A clear example of this is Transaction.prototype.getSenderPublicKey's implementation.

Created this issue to continue the discussion started in ethereumjs/ethereumjs-tx#142 and to garner feedback whether you think this'd make sense. Here's a rough sketch of one (non-breaking) approach that comes to my mind:

Make TxData a class, and use it to store the actual data for the transaction, plus methods for serialization/deserialization. In Transaction's constructor instantiate TxData and store it for later use (possibly add a static fromTxData method). Logic methods stay on Transaction and use TxData as source of data but do not mutate it.

If this is too vague I can try to write up (or a diagram) of something more concrete. Please feel free to propose other ideas.

What I don't understand is how to make this in a non-breaking way. At least not without keeping everything with side-effects.

@s1na
Copy link
Contributor Author

s1na commented May 10, 2019

What I don't understand is how to make this in a non-breaking way.

Hm, you're right. It could be possible to have it non-breaking by having getters for values on Transaction. But that won't be an improvement to the current design...

@alcuadrado What do you propose? I think some breaking change is inevitable.

@alcuadrado
Copy link
Member

A good way to move forward may be to do a clean redesign of the library, and then evaluate if it makes sense to replace it entirely or only we want part of the changes. There's the possibility of some work not ending up in the library, but we get to experiment with solving all those things.

I can do this if we agree that it's something that we want to do.

@danjm, you mentioned in ethereumjs/ethereumjs-tx#142 that you had some ideas about redesigning this lib. Mind sharing them? Thanks!

@rajeshsubhankar
Copy link

rajeshsubhankar commented May 11, 2019

[DELETED BY EDITOR @holgerd77, OUT OF TOPIC]

@holgerd77
Copy link
Member

Hi @rajeshsubhankar, your comment had absolutely nothing to do with the issue discussed here, please make sure that you do comments or open issues where it fits.

Have deleted your post and re-posted as a new issue, see above.

@alcuadrado
Copy link
Member

I agree with moving that to a different issue, but we should note that what @rajeshsubhankar describes as "Use case 2" is important for this discussion.

Basically, he is having problems with setting and verifying a signature after constructing the TX object. The problem is that the TX object only computes the chainId on construction, not on the v setter.

@alcuadrado
Copy link
Member

alcuadrado commented May 18, 2019

Hey @s1na, I created PR ethereumjs/ethereumjs-tx#154 to explore one possibility of what we can do with this and other libraries.

The idea of that PR is to keep everything as explicit as possible. Transaction APIs now work with buffers, with the only exception of static factory methods added for the users' convenience.

In this new version, transactions aren't immutable either, but only sign and the setters mutate them.

It has about 60 lines more of boilerplate, but I think it's a fair price for making it much easier to understand and work with.

PS: I really dislike some of the names I gave to interfaces.

@evertonfraga evertonfraga transferred this issue from ethereumjs/ethereumjs-tx Apr 6, 2020
@ryanio ryanio mentioned this issue Sep 15, 2020
@ryanio
Copy link
Contributor

ryanio commented Sep 22, 2020

Resolved with #812

@ryanio ryanio closed this as completed Sep 22, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants