-
Notifications
You must be signed in to change notification settings - Fork 106
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
Add tipping tx subtype #260
Changes from 35 commits
4fb310d
e1cc692
de1b3e6
dbd9780
da0917b
3fdc17c
8c86873
d21ef14
66e7bdb
cf55b99
964d825
1126004
b9c1c4e
9380b87
a9739e1
bcec1f8
35b2da6
47eac23
d650824
3a54079
43a7d13
d4d6370
e4d6af3
ce5b737
873384d
88498e8
8952bb9
d59a026
fe9d3e3
980abc5
bd4b275
1324ffd
b430ae6
bcb7de4
c7b244d
0f09b6d
43ab2a1
8d925b3
2cf65c2
7594ef3
8ac00e8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package types | ||
|
||
import ( | ||
"fmt" | ||
"math/big" | ||
|
||
"github.com/ethereum/go-ethereum/common" | ||
|
@@ -40,6 +41,20 @@ func (s arbitrumSigner) Sender(tx *Transaction) (common.Address, error) { | |
} | ||
fakeTx := NewTx(&legacyData.LegacyTx) | ||
return s.Signer.Sender(fakeTx) | ||
case *ArbitrumSubtypedTx: | ||
switch inner.TxData.(type) { | ||
case *ArbitrumTippingTx: | ||
V, R, S := tx.RawSignatureValues() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 3 options, I'm o.k. with any:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2 - we can't make fake so I went with 1 and added a comment. In |
||
// DynamicFee txs are defined to use 0 and 1 as their recovery | ||
// id, add 27 to become equivalent to unprotected Homestead signatures. | ||
V = new(big.Int).Add(V, big.NewInt(27)) | ||
if tx.ChainId().Cmp(s.Signer.ChainID()) != 0 { | ||
return common.Address{}, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, tx.ChainId(), s.Signer.ChainID()) | ||
} | ||
return recoverPlain(s.Hash(tx), R, S, V, true) | ||
default: | ||
return common.Address{}, ErrTxTypeNotSupported | ||
} | ||
default: | ||
return s.Signer.Sender(tx) | ||
} | ||
|
@@ -51,7 +66,7 @@ func (s arbitrumSigner) Equal(s2 Signer) bool { | |
} | ||
|
||
func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *big.Int, err error) { | ||
switch tx.inner.(type) { | ||
switch inner := tx.inner.(type) { | ||
case *ArbitrumUnsignedTx: | ||
return bigZero, bigZero, bigZero, nil | ||
case *ArbitrumContractTx: | ||
|
@@ -65,9 +80,22 @@ func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *b | |
case *ArbitrumSubmitRetryableTx: | ||
return bigZero, bigZero, bigZero, nil | ||
case *ArbitrumLegacyTxData: | ||
legacyData := tx.inner.(*ArbitrumLegacyTxData) | ||
fakeTx := NewTx(&legacyData.LegacyTx) | ||
fakeTx := NewTx(&inner.LegacyTx) | ||
return s.Signer.SignatureValues(fakeTx, sig) | ||
case *ArbitrumSubtypedTx: | ||
switch txdata := inner.TxData.(type) { | ||
case *ArbitrumTippingTx: | ||
// Check that chain ID of tx matches the signer. We also accept ID zero here, | ||
// because it indicates that the chain ID was not specified in the tx. | ||
if txdata.ChainID.Sign() != 0 && txdata.ChainID.Cmp(s.Signer.ChainID()) != 0 { | ||
return nil, nil, nil, fmt.Errorf("%w: have %d want %d", ErrInvalidChainId, txdata.ChainID, s.Signer.ChainID()) | ||
} | ||
R, S, _ = decodeSignature(sig) | ||
V = big.NewInt(int64(sig[64])) | ||
return R, S, V, nil | ||
default: | ||
return nil, nil, nil, ErrTxTypeNotSupported | ||
} | ||
default: | ||
return s.Signer.SignatureValues(tx, sig) | ||
} | ||
|
@@ -76,9 +104,28 @@ func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *b | |
// Hash returns the hash to be signed by the sender. | ||
// It does not uniquely identify the transaction. | ||
func (s arbitrumSigner) Hash(tx *Transaction) common.Hash { | ||
if legacyData, isArbLegacy := tx.inner.(*ArbitrumLegacyTxData); isArbLegacy { | ||
fakeTx := NewTx(&legacyData.LegacyTx) | ||
switch inner := tx.inner.(type) { | ||
case *ArbitrumLegacyTxData: | ||
fakeTx := NewTx(&inner.LegacyTx) | ||
return s.Signer.Hash(fakeTx) | ||
case *ArbitrumSubtypedTx: | ||
switch inner.TxData.(type) { | ||
case *ArbitrumTippingTx: | ||
return prefixedRlpHash( | ||
tx.Type(), | ||
[]interface{}{ | ||
inner.TxSubtype(), | ||
s.Signer.ChainID(), | ||
tx.Nonce(), | ||
tx.GasTipCap(), | ||
tx.GasFeeCap(), | ||
tx.Gas(), | ||
tx.To(), | ||
tx.Value(), | ||
tx.Data(), | ||
tx.AccessList(), | ||
}) | ||
} | ||
} | ||
return s.Signer.Hash(tx) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -41,18 +41,18 @@ var ( | |
|
||
// Transaction types. | ||
const ( | ||
ArbitrumDepositTxType = 0x64 | ||
ArbitrumUnsignedTxType = 0x65 | ||
ArbitrumContractTxType = 0x66 | ||
ArbitrumRetryTxType = 0x68 | ||
ArbitrumSubmitRetryableTxType = 0x69 | ||
ArbitrumInternalTxType = 0x6A | ||
ArbitrumLegacyTxType = 0x78 | ||
|
||
LegacyTxType = 0x00 | ||
AccessListTxType = 0x01 | ||
DynamicFeeTxType = 0x02 | ||
BlobTxType = 0x03 | ||
ArbitrumSubtypedTxType = 99 | ||
ArbitrumDepositTxType = 100 | ||
ArbitrumUnsignedTxType = 101 | ||
ArbitrumContractTxType = 102 | ||
ArbitrumRetryTxType = 104 | ||
ArbitrumSubmitRetryableTxType = 105 | ||
ArbitrumInternalTxType = 106 | ||
ArbitrumLegacyTxType = 120 | ||
LegacyTxType = 0x00 | ||
magicxyyz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
AccessListTxType = 0x01 | ||
DynamicFeeTxType = 0x02 | ||
BlobTxType = 0x03 | ||
) | ||
|
||
// Transaction is an Ethereum transaction. | ||
|
@@ -244,6 +244,10 @@ func (tx *Transaction) decodeTyped(b []byte, arbParsing bool) (TxData, error) { | |
var inner BlobTx | ||
err := rlp.DecodeBytes(b[1:], &inner) | ||
return &inner, err | ||
case ArbitrumSubtypedTxType: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this belongs a few lines up - under There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we need to parse |
||
var inner ArbitrumSubtypedTx | ||
err := rlp.DecodeBytes(b[1:], &inner) | ||
return &inner, err | ||
default: | ||
return nil, ErrTxTypeNotSupported | ||
} | ||
|
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 I get it but I still find it kind of confusing and a room for error..
could we add a separate subtype field in SubtypedTx and use that?
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'd be great to keep the subtype a constant, but adding a field invalidates the property
Maybe I should add a
func (tx *ArbitrumSubtypedTx) SubTx() TxData
method, and then we'd use it this way:tx.SubTx().Type()
, would it be better?