Skip to content

Commit

Permalink
Expand custom arb tx types
Browse files Browse the repository at this point in the history
  • Loading branch information
PlasmaPower authored and hkalodner committed Oct 19, 2021
1 parent 127a870 commit 694bf69
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 48 deletions.
86 changes: 48 additions & 38 deletions core/types/arb_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ import (

var bigZero = big.NewInt(0)

func (tx *LegacyTx) isFake() bool { return false }
func (tx *LegacyTx) isFake() bool { return false }
func (tx *AccessListTx) isFake() bool { return false }
func (tx *DynamicFeeTx) isFake() bool { return false }

type ArbitrumUnsignedTx struct {
ChainId *big.Int
From common.Address
From common.Address

Nonce uint64 // nonce of sender account
GasPrice *big.Int // wei per gas
Expand All @@ -24,18 +24,17 @@ type ArbitrumUnsignedTx struct {
Data []byte // contract invocation input data
}


func (tx *ArbitrumUnsignedTx) txType() byte { return ArbitrumUnsignedTxType }

func (tx *ArbitrumUnsignedTx) copy() TxData {
cpy := &ArbitrumUnsignedTx{
ChainId: new(big.Int),
Nonce: tx.Nonce,
GasPrice: new(big.Int),
Gas: tx.Gas,
To: nil,
Value: new(big.Int),
Data: common.CopyBytes(tx.Data),
ChainId: new(big.Int),
Nonce: tx.Nonce,
GasPrice: new(big.Int),
Gas: tx.Gas,
To: nil,
Value: new(big.Int),
Data: common.CopyBytes(tx.Data),
}
if tx.ChainId != nil {
cpy.ChainId.Set(tx.ChainId)
Expand Down Expand Up @@ -63,7 +62,7 @@ func (tx *ArbitrumUnsignedTx) gasFeeCap() *big.Int { return tx.GasPrice }
func (tx *ArbitrumUnsignedTx) value() *big.Int { return tx.Value }
func (tx *ArbitrumUnsignedTx) nonce() uint64 { return tx.Nonce }
func (tx *ArbitrumUnsignedTx) to() *common.Address { return tx.To }
func (tx *ArbitrumUnsignedTx) isFake() bool { return false }
func (tx *ArbitrumUnsignedTx) isFake() bool { return false }

func (tx *ArbitrumUnsignedTx) rawSignatureValues() (v, r, s *big.Int) {
return bigZero, bigZero, bigZero
Expand All @@ -74,9 +73,9 @@ func (tx *ArbitrumUnsignedTx) setSignatureValues(chainID, v, r, s *big.Int) {
}

type ArbitrumContractTx struct {
ChainId *big.Int
ChainId *big.Int
RequestId common.Hash
From common.Address
From common.Address

GasPrice *big.Int // wei per gas
Gas uint64 // gas limit
Expand All @@ -85,7 +84,6 @@ type ArbitrumContractTx struct {
Data []byte // contract invocation input data
}


func (tx *ArbitrumContractTx) txType() byte { return ArbitrumContractTxType }

func (tx *ArbitrumContractTx) copy() TxData {
Expand Down Expand Up @@ -128,24 +126,24 @@ func (tx *ArbitrumContractTx) rawSignatureValues() (v, r, s *big.Int) {
return bigZero, bigZero, bigZero
}
func (tx *ArbitrumContractTx) setSignatureValues(chainID, v, r, s *big.Int) {}
func (tx *ArbitrumContractTx) isFake() bool { return true }
func (tx *ArbitrumContractTx) isFake() bool { return true }

type DepositTx struct {
ChainId *big.Int
type ArbitrumDepositTx struct {
ChainId *big.Int
L1RequestId common.Hash
To common.Address
Value *big.Int
To common.Address
Value *big.Int
}

func (d *DepositTx) txType() byte {
func (d *ArbitrumDepositTx) txType() byte {
return ArbitrumDepositTxType
}

func (d *DepositTx) copy() TxData {
tx := &DepositTx{
func (d *ArbitrumDepositTx) copy() TxData {
tx := &ArbitrumDepositTx{
ChainId: new(big.Int),
To: d.To,
Value: new(big.Int),
To: d.To,
Value: new(big.Int),
}
if d.ChainId != nil {
tx.ChainId.Set(d.ChainId)
Expand All @@ -156,23 +154,35 @@ func (d *DepositTx) copy() TxData {
return tx
}

func (d *DepositTx) chainID() *big.Int { return d.ChainId }
func (d *DepositTx) accessList() AccessList { return nil }
func (d *DepositTx) data() []byte { return nil }
func (d DepositTx) gas() uint64 { return 0 }
func (d *DepositTx) gasPrice() *big.Int { return bigZero }
func (d *DepositTx) gasTipCap() *big.Int { return bigZero }
func (d *DepositTx) gasFeeCap() *big.Int { return bigZero }
func (d *DepositTx) value() *big.Int { return d.Value }
func (d *DepositTx) nonce() uint64 { return 0 }
func (d *DepositTx) to() *common.Address { return &d.To }
func (d *DepositTx) isFake() bool { return true }

func (d *DepositTx) rawSignatureValues() (v, r, s *big.Int) {
func (d *ArbitrumDepositTx) chainID() *big.Int { return d.ChainId }
func (d *ArbitrumDepositTx) accessList() AccessList { return nil }
func (d *ArbitrumDepositTx) data() []byte { return nil }
func (d ArbitrumDepositTx) gas() uint64 { return 0 }
func (d *ArbitrumDepositTx) gasPrice() *big.Int { return bigZero }
func (d *ArbitrumDepositTx) gasTipCap() *big.Int { return bigZero }
func (d *ArbitrumDepositTx) gasFeeCap() *big.Int { return bigZero }
func (d *ArbitrumDepositTx) value() *big.Int { return d.Value }
func (d *ArbitrumDepositTx) nonce() uint64 { return 0 }
func (d *ArbitrumDepositTx) to() *common.Address { return &d.To }
func (d *ArbitrumDepositTx) isFake() bool { return true }

func (d *ArbitrumDepositTx) rawSignatureValues() (v, r, s *big.Int) {
return bigZero, bigZero, bigZero
}

func (d *DepositTx) setSignatureValues(chainID, v, r, s *big.Int) {
func (d *ArbitrumDepositTx) setSignatureValues(chainID, v, r, s *big.Int) {

}

type ArbitrumWrappedTx struct {
l1Calldata uint64
TxData
}

func (tx *ArbitrumWrappedTx) copy() TxData {
cpy := &ArbitrumWrappedTx{
l1Calldata: tx.l1Calldata,
TxData: tx.TxData.copy(),
}
return cpy
}
6 changes: 3 additions & 3 deletions core/types/arbitrum_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (

var arbAddress = common.HexToAddress("0xabc")

type arbitrumSigner struct { Signer }
type arbitrumSigner struct{ Signer }

func NewArbitrumSigner(signer Signer) Signer {
return arbitrumSigner{Signer: signer}
Expand All @@ -20,7 +20,7 @@ func (s arbitrumSigner) Sender(tx *Transaction) (common.Address, error) {
return inner.From, nil
case *ArbitrumContractTx:
return inner.From, nil
case *DepositTx:
case *ArbitrumDepositTx:
return arbAddress, nil
default:
return s.Signer.Sender(tx)
Expand All @@ -38,7 +38,7 @@ func (s arbitrumSigner) SignatureValues(tx *Transaction, sig []byte) (R, S, V *b
return bigZero, bigZero, bigZero, nil
case *ArbitrumContractTx:
return bigZero, bigZero, bigZero, nil
case *DepositTx:
case *ArbitrumDepositTx:
return bigZero, bigZero, bigZero, nil
default:
return s.Signer.SignatureValues(tx, sig)
Expand Down
44 changes: 39 additions & 5 deletions core/types/transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ const (
ArbitrumDepositTxType = 200
ArbitrumUnsignedTxType = 201
ArbitrumContractTxType = 202
ArbitrumWrappedTxType = 203
)

// Transaction is an Ethereum transaction.
Expand Down Expand Up @@ -94,7 +95,7 @@ type TxData interface {

// EncodeRLP implements rlp.Encoder
func (tx *Transaction) EncodeRLP(w io.Writer) error {
if tx.Type() == LegacyTxType {
if tx.realType() == LegacyTxType {
return rlp.Encode(w, tx.inner)
}
// It's an EIP-2718 typed TX envelope.
Expand All @@ -109,7 +110,7 @@ func (tx *Transaction) EncodeRLP(w io.Writer) error {

// encodeTyped writes the canonical encoding of a typed transaction to w.
func (tx *Transaction) encodeTyped(w *bytes.Buffer) error {
w.WriteByte(tx.Type())
w.WriteByte(tx.realType())
return rlp.Encode(w, tx.inner)
}

Expand Down Expand Up @@ -145,7 +146,7 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
if b, err = s.Bytes(); err != nil {
return err
}
inner, err := tx.decodeTyped(b)
inner, err := tx.decodeTyped(b, true)
if err == nil {
tx.setDecoded(inner, len(b))
}
Expand All @@ -169,7 +170,7 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error {
return nil
}
// It's an EIP2718 typed transaction envelope.
inner, err := tx.decodeTyped(b)
inner, err := tx.decodeTyped(b, false)
if err != nil {
return err
}
Expand All @@ -178,10 +179,30 @@ func (tx *Transaction) UnmarshalBinary(b []byte) error {
}

// decodeTyped decodes a typed transaction from the canonical format.
func (tx *Transaction) decodeTyped(b []byte) (TxData, error) {
func (tx *Transaction) decodeTyped(b []byte, arbParsing bool) (TxData, error) {
if len(b) == 0 {
return nil, errEmptyTypedTx
}
if arbParsing {
switch b[0] {
case ArbitrumDepositTxType:
var inner ArbitrumDepositTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
case ArbitrumUnsignedTxType:
var inner ArbitrumUnsignedTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
case ArbitrumContractTxType:
var inner ArbitrumContractTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
case ArbitrumWrappedTxType:
var inner ArbitrumWrappedTx
err := rlp.DecodeBytes(b[1:], &inner)
return &inner, err
}
}
switch b[0] {
case AccessListTxType:
var inner AccessListTx
Expand Down Expand Up @@ -255,6 +276,19 @@ func (tx *Transaction) Type() uint8 {
return tx.inner.txType()
}

func (tx *Transaction) realType() uint8 {
_, isArbWrapped := tx.inner.(*ArbitrumWrappedTx)
if isArbWrapped {
return ArbitrumWrappedTxType
} else {
return tx.Type()
}
}

func (tx *Transaction) GetInner() TxData {
return tx.inner.copy()
}

// ChainId returns the EIP155 chain ID of the transaction. The return value will always be
// non-nil. For legacy transactions which are not replay-protected, the return value is
// zero.
Expand Down
12 changes: 10 additions & 2 deletions core/types/transaction_signing.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func MakeSigner(config *params.ChainConfig, blockNumber *big.Int) Signer {
//
// Use this in transaction-handling code where the current block number is unknown. If you
// have the current block number available, use MakeSigner instead.
func LatestSigner(config *params.ChainConfig) Signer {
func latestSignerImpl(config *params.ChainConfig) Signer {
if config.ChainID != nil {
if config.LondonBlock != nil {
return NewLondonSigner(config.ChainID)
Expand All @@ -79,20 +79,28 @@ func LatestSigner(config *params.ChainConfig) Signer {
return HomesteadSigner{}
}

func LatestSigner(config *params.ChainConfig) Signer {
return NewArbitrumSigner(latestSignerImpl(config))
}

// LatestSignerForChainID returns the 'most permissive' Signer available. Specifically,
// this enables support for EIP-155 replay protection and all implemented EIP-2718
// transaction types if chainID is non-nil.
//
// Use this in transaction-handling code where the current block number and fork
// configuration are unknown. If you have a ChainConfig, use LatestSigner instead.
// If you have a ChainConfig and know the current block number, use MakeSigner instead.
func LatestSignerForChainID(chainID *big.Int) Signer {
func latestSignerForChainIDImpl(chainID *big.Int) Signer {
if chainID == nil {
return HomesteadSigner{}
}
return NewLondonSigner(chainID)
}

func LatestSignerForChainID(chainID *big.Int) Signer {
return NewArbitrumSigner(latestSignerForChainIDImpl(chainID))
}

// SignTx signs the transaction using the given signer and private key.
func SignTx(tx *Transaction, s Signer, prv *ecdsa.PrivateKey) (*Transaction, error) {
h := s.Hash(tx)
Expand Down

0 comments on commit 694bf69

Please sign in to comment.