-
Notifications
You must be signed in to change notification settings - Fork 104
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
Break the unsigned transaction data out of the transaction #1640
Conversation
chain/signedtxn.go
Outdated
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 it's actually easier to review this file if the struct definition is kept in transaction.go
because so it shows up as a rename instead of a delete + add
chain/signedtxn.go
Outdated
stateKeys state.Keys | ||
} | ||
|
||
func (t *SignedTransaction) UnsignedTxnBytes() []byte { return t.Transaction.bytes } |
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.
- nit: I prefer the receiver name being
s
since it's the first letter of the struct name. - Seems like we don't need this function since you can just call
signedTx.UnsignedBytes()
becauseTransaction
is an embedded type.
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.
Regarding the second one, the main advantage in having the UnsignedTxnBytes
in SignedTransaction
is that it doesn't need to return a potential error
. The error case was already handled during the unmarshaler, so no error handling is required by the caller.
chain/transaction.go
Outdated
if len(t.unsignedBytes) > 0 { | ||
return t.unsignedBytes, nil | ||
// Bytes returns the byte slice representation of the tx | ||
func (t *Transaction) Bytes() ([]byte, error) { |
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.
Seems to me like the diff in this function isn't needed
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.
done
chain/transaction.go
Outdated
t.Base.Marshal(p) | ||
if err := t.Actions.marshalInto(p); err != nil { | ||
if err := p.Err(); err != nil { |
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 diff isn't needed since Packer
will stop at the first error (ref).
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 see.. so you're saying that adding this would have no practical functional impact since the packet would effectively be "blocked" for any new additions due to the error.
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.
done
chain/signedtxn.go
Outdated
_ mempool.Item = (*SignedTransaction)(nil) | ||
) | ||
|
||
type SignedTransaction struct { |
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'm not sure how I feel about this naming. I personally get pretty confused seeing SignedTransaction
and Transaction
as I keep assuming Transaction
is signed. We could consider something else like SignedTransaction
and UnsignedTransaction
or Transaction
and TransactionData
.
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.
It looks like we have only several places the use the unsigned transaction. Therefore, I'm not really opinionated here. I've changed the following:
SignedTransaction -> Transaction
Transaction -> TransactionData
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.
Few small nits and then this LGTM - thanks for cleaning this up, this makes it way easier to reason about the fields of a transaction that have been populated
api/jsonrpc/client.go
Outdated
@@ -170,8 +170,8 @@ func (cli *JSONRPCClient) GenerateTransactionManual( | |||
|
|||
// Build transaction | |||
actionCodec, authCodec := parser.ActionCodec(), parser.AuthCodec() | |||
tx := chain.NewTx(base, actions) | |||
tx, err := tx.Sign(authFactory, actionCodec, authCodec) | |||
unsignedTx := chain.NewTxnData(base, actions) |
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.
Can we change to NewTxData
? We typically use tx instead of txn
tests/integration/integration.go
Outdated
@@ -360,9 +360,12 @@ var _ = ginkgo.Describe("[Tx Processing]", ginkgo.Serial, func() { | |||
require.NoError(err) | |||
auth, err := authFactory.Sign(unsignedTxBytes) | |||
require.NoError(err) | |||
tx.Auth = auth | |||
signedTxn := chain.Transaction{ |
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.
Could we use signedTx
instead of signedTxn
?
vm/vm.go
Outdated
continue | ||
} | ||
if err := tx.Auth.Verify(ctx, unsignedTxBytes); err != nil { | ||
if err := tx.Verify(ctx); err != nil { |
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.
Can we update the function name to VerifyAuth
so that it's explicit what's being verified vs. Execute
and PreExecute
?
chain/transaction_test.go
Outdated
// call Bytes so that the "bytes" field would get populated. | ||
_, err = txBeforeSign.UnsignedBytes() | ||
require.NoError(err) |
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.
(not necessary for this PR) would it make sense to always create TransactionData
via a single constructor, so that it's clear all of the fields are populated in one place?
@@ -28,28 +28,23 @@ var ( | |||
_ mempool.Item = (*Transaction)(nil) | |||
) | |||
|
|||
type Transaction struct { | |||
type TransactionData struct { |
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.
❤️ makes this way easier to review
chain/transaction.go
Outdated
|
||
func (t *Transaction) ID() ids.ID { return t.id } | ||
func (s *Transaction) Bytes() []byte { return s.bytes } |
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.
Can we change from using (s *Transaction)
to (t *Transaction)
to follow the convention of using the lowercase first letter of the type?
What ?
Break the existing
Transaction
struct intoTransaction
and an embedded structTransactionData
Why ?
The usage of
Transaction
might not be sufficient to distinguish between the sign and the unsigned transaction.The unsigned transaction ( i.e.
TransactionData
) should be used only in the case of a new transaction being created, and before it's being signed.The signed transaction should be used everywhere else. For that reason, the
Transaction
doesn't come with any constructor of it's own ( only marshaler/unmarshaler ).