Skip to content
This repository has been archived by the owner on Apr 11, 2021. It is now read-only.

ethapi: adds txmeta fields to transaction rpc responses #35

Merged
merged 7 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions core/types/gen_tx_meta_json.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

49 changes: 38 additions & 11 deletions core/types/transaction_meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,43 @@ package types
import (
"bytes"
"encoding/binary"
"math/big"

"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/common/hexutil"
)

//go:generate gencodec -type TransactionMeta -out gen_tx_meta_json.go

type TransactionMeta struct {
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId"`
L1MessageSender *common.Address `json:"l1MessageSender"`
SignatureHashType SignatureHashType `json:"signatureHashType"`
L1RollupTxId *hexutil.Uint64 `json:"l1RollupTxId" gencodec:"required"`
L1MessageSender *common.Address `json:"l1MessageSender" gencodec:"required"`
SignatureHashType SignatureHashType `json:"signatureHashType" gencodec:"required"`
QueueOrigin *big.Int `json:"queueOrigin" gencodec:"required"`
}

// Hard code the queue origin as 2 since it represents the origin as the
// sequencer. Add the queue origin to the function signature once l1 transaction
// ingestion is ready.
func NewTransactionMeta(L1RollupTxId *hexutil.Uint64, L1MessageSender *common.Address, sighashType SignatureHashType) *TransactionMeta {
return &TransactionMeta{L1RollupTxId: L1RollupTxId, L1MessageSender: L1MessageSender, SignatureHashType: sighashType}
queueOrigin := new(big.Int).SetUint64(2)
return &TransactionMeta{L1RollupTxId: L1RollupTxId, L1MessageSender: L1MessageSender, SignatureHashType: sighashType, QueueOrigin: queueOrigin}
}

// TxMetaDecode deserializes bytes as a TransactionMeta struct.
// The schema is:
// varbytes(SignatureHashType) || varbytes(L1RollupTxId) || varbytes(L1MessageSender)
// varbytes(SignatureHashType) ||
// varbytes(L1RollupTxId) ||
// varbytes(L1MessageSender) ||
// varbytes(QueueOrigin)
func TxMetaDecode(input []byte) (*TransactionMeta, error) {
var err error
meta := TransactionMeta{}

b := bytes.NewReader(input)

sb, err := common.ReadVarBytes(b, 0, 1024, "SignatureHashType")
if err != nil {
return &TransactionMeta{}, err
return nil, err
}

var sighashType SignatureHashType
Expand All @@ -42,9 +52,8 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {

lb, err := common.ReadVarBytes(b, 0, 1024, "L1RollupTxId")
if err != nil {
return &TransactionMeta{}, err
return nil, err
}

if !isNullValue(lb) {
var l1RollupTxId hexutil.Uint64
binary.Read(bytes.NewReader(lb), binary.LittleEndian, &l1RollupTxId)
Expand All @@ -53,15 +62,23 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {

mb, err := common.ReadVarBytes(b, 0, 1024, "L1MessageSender")
if err != nil {
return &TransactionMeta{}, err
return nil, err
}

if !isNullValue(mb) {
var l1MessageSender common.Address
binary.Read(bytes.NewReader(mb), binary.LittleEndian, &l1MessageSender)
meta.L1MessageSender = &l1MessageSender
}

qo, err := common.ReadVarBytes(b, 0, 1024, "QueueOrigin")
if err != nil {
return nil, err
}
if !isNullValue(qo) {
queueOrigin := new(big.Int).SetBytes(qo)
meta.QueueOrigin = queueOrigin
}

return &meta, nil
}

Expand Down Expand Up @@ -91,9 +108,19 @@ func TxMetaEncode(meta *TransactionMeta) []byte {
common.WriteVarBytes(b, 0, l.Bytes())
}

queueOrigin := meta.QueueOrigin
if queueOrigin == nil {
common.WriteVarBytes(b, 0, getNullValue())
} else {
q := new(bytes.Buffer)
binary.Write(q, binary.LittleEndian, queueOrigin.Bytes())
common.WriteVarBytes(b, 0, q.Bytes())
}

return b.Bytes()
}

// This may collide with a uint8
func isNullValue(b []byte) bool {
nullValue := []byte{0x00}
return bytes.Equal(b, nullValue)
Expand Down
36 changes: 36 additions & 0 deletions core/types/transaction_meta_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"bytes"
"math/big"
"testing"

"github.com/ethereum/go-ethereum/common"
Expand All @@ -16,21 +17,43 @@ var (
txid *hexutil.Uint64
msgSender *common.Address
sighashType SignatureHashType
queueOrigin *big.Int
}{
{
txid: &txid,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: big.NewInt(2),
},
{
txid: nil,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: big.NewInt(2),
},
{
txid: &txid,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: big.NewInt(2),
},
{
txid: &txid,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: nil,
},
{
txid: nil,
msgSender: nil,
sighashType: SighashEthSign,
queueOrigin: nil,
},
{
txid: &txid,
msgSender: &addr,
sighashType: SighashEthSign,
queueOrigin: big.NewInt(0),
},
}

Expand All @@ -52,6 +75,8 @@ var (
func TestTransactionMetaEncode(t *testing.T) {
for _, test := range txMetaSerializationTests {
txmeta := NewTransactionMeta(test.txid, test.msgSender, test.sighashType)
txmeta.QueueOrigin = test.queueOrigin

encoded := TxMetaEncode(txmeta)
decoded, err := TxMetaDecode(encoded)

Expand Down Expand Up @@ -106,5 +131,16 @@ func isTxMetaEqual(meta1 *TransactionMeta, meta2 *TransactionMeta) bool {
return false
}

if meta1.QueueOrigin == nil || meta2.QueueOrigin == nil {
// Note: this only works because it is the final comparison
if meta1.QueueOrigin == nil && meta2.QueueOrigin == nil {
return true
}
}

if !bytes.Equal(meta1.QueueOrigin.Bytes(), meta2.QueueOrigin.Bytes()) {
return false
}

return true
}
26 changes: 24 additions & 2 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1059,6 +1059,9 @@ type RPCTransaction struct {
V *hexutil.Big `json:"v"`
R *hexutil.Big `json:"r"`
S *hexutil.Big `json:"s"`
QueueOrigin string `json:"queueOrigin"`
Type string `json:"type"`
L1MessageSender *common.Address `json:"l1MessageSender"`
}

// newRPCTransaction returns a transaction that will serialize to the RPC
Expand Down Expand Up @@ -1090,6 +1093,23 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
result.BlockNumber = (*hexutil.Big)(new(big.Int).SetUint64(blockNumber))
result.TransactionIndex = (*hexutil.Uint64)(&index)
}

if meta := tx.GetMeta(); meta != nil {
result.L1MessageSender = meta.L1MessageSender
if meta.QueueOrigin != nil {
switch meta.QueueOrigin.Uint64() {
case uint64(2):
result.QueueOrigin = "sequencer"
}
}

switch meta.SignatureHashType {
case types.SighashEthSign:
result.Type = "EthSign"
case types.SighashEIP155:
result.Type = "EIP155"
}
}
return result
}

Expand Down Expand Up @@ -1508,6 +1528,8 @@ func (s *PublicTransactionPoolAPI) SendRawTransaction(ctx context.Context, encod
if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err
}
meta := types.NewTransactionMeta(nil, nil, types.SighashEIP155)
tx.SetTransactionMeta(meta)
return SubmitTransaction(ctx, s.b, tx)
}

Expand All @@ -1520,8 +1542,8 @@ func (s *PublicTransactionPoolAPI) SendRawEthSignTransaction(ctx context.Context
if err := rlp.DecodeBytes(encodedTx, tx); err != nil {
return common.Hash{}, err
}

tx.SetSignatureHashType(types.SighashEthSign)
meta := types.NewTransactionMeta(nil, nil, types.SighashEthSign)
tx.SetTransactionMeta(meta)
return SubmitTransaction(ctx, s.b, tx)
}

Expand Down