Commit 08873674 authored by Karl Floersch's avatar Karl Floersch Committed by GitHub

refactor[l2geth]: queue origin type (#975)

* refactor: queueOrigin type

* Convert queueOrigin to uint8 in encode

* Add changeset

* Regenerate json marshall

* style: combine lines

* Add Stringer for QueueOrigin

* Turn QueueOrigin into uint8

* l2geth: gen tx meta fix

* l2geth: gen tx meta fix

* lint
Co-authored-by: default avatarMark Tyneway <mark.tyneway@gmail.com>
parent c54de600
---
'@eth-optimism/l2geth': patch
---
Update queueOrigin type
......@@ -603,7 +603,7 @@ func (m callmsg) Data() []byte { return m.CallMsg.Data }
func (m callmsg) L1MessageSender() *common.Address { return m.CallMsg.L1MessageSender }
func (m callmsg) L1BlockNumber() *big.Int { return m.CallMsg.L1BlockNumber }
func (m callmsg) QueueOrigin() *big.Int { return m.CallMsg.QueueOrigin }
func (m callmsg) QueueOrigin() types.QueueOrigin { return m.CallMsg.QueueOrigin }
// filterBackend implements filters.Backend to support filtering for logs without
// taking bloom-bits acceleration structures into account.
......
......@@ -77,7 +77,7 @@ type Message interface {
Data() []byte
L1MessageSender() *common.Address
L1BlockNumber() *big.Int
QueueOrigin() *big.Int
QueueOrigin() types.QueueOrigin
}
// IntrinsicGas computes the 'intrinsic gas' for a message with the given data.
......@@ -184,9 +184,7 @@ func (st *StateTransition) preCheck() error {
if nonce < st.msg.Nonce() {
if vm.UsingOVM {
// The nonce never increments for L1ToL2 txs
qo := st.msg.QueueOrigin()
l1ToL2 := uint64(types.QueueOriginL1ToL2)
if qo != nil && qo.Uint64() == l1ToL2 {
if st.msg.QueueOrigin() == types.QueueOriginL1ToL2 {
return st.buyGas()
}
}
......
......@@ -26,7 +26,7 @@ func toExecutionManagerRun(evm *vm.EVM, msg Message) (Message, error) {
tx := ovmTransaction{
evm.Context.Time,
msg.L1BlockNumber(),
uint8(msg.QueueOrigin().Uint64()),
uint8(msg.QueueOrigin()),
*msg.L1MessageSender(),
*msg.To(),
big.NewInt(int64(msg.Gas())),
......@@ -73,8 +73,7 @@ func AsOvmMessage(tx *types.Transaction, signer types.Signer, decompressor commo
// sequencer entrypoint. The calldata is expected to be in the
// correct format when deserialized from the EVM events, see
// rollup/sync_service.go.
qo := msg.QueueOrigin()
if qo != nil && qo.Uint64() == uint64(types.QueueOriginL1ToL2) {
if msg.QueueOrigin() == types.QueueOriginL1ToL2 {
return msg, nil
}
......@@ -104,7 +103,7 @@ func EncodeSimulatedMessage(msg Message, timestamp, blockNumber *big.Int, execut
tx := ovmTransaction{
timestamp,
blockNumber,
uint8(msg.QueueOrigin().Uint64()),
uint8(msg.QueueOrigin()),
*msg.L1MessageSender(),
*to,
big.NewInt(int64(msg.Gas())),
......@@ -139,11 +138,6 @@ func modMessage(
data []byte,
gasLimit uint64,
) (Message, error) {
queueOrigin, err := getQueueOrigin(msg.QueueOrigin())
if err != nil {
return nil, err
}
outmsg := types.NewMessage(
from,
to,
......@@ -155,22 +149,8 @@ func modMessage(
false,
msg.L1MessageSender(),
msg.L1BlockNumber(),
queueOrigin,
msg.QueueOrigin(),
)
return outmsg, nil
}
func getQueueOrigin(
queueOrigin *big.Int,
) (types.QueueOrigin, error) {
if queueOrigin.Cmp(big.NewInt(0)) == 0 {
return types.QueueOriginSequencer, nil
} else if queueOrigin.Cmp(big.NewInt(1)) == 0 {
return types.QueueOriginL1ToL2, nil
} else if queueOrigin.Cmp(big.NewInt(2)) == 0 {
return types.QueueOriginL1ToL2, nil
} else {
return types.QueueOriginSequencer, fmt.Errorf("invalid queue origin: %d", queueOrigin)
}
}
......@@ -13,8 +13,8 @@ import (
var _ = (*txdataMarshaling)(nil)
// TransactionMarshalJSON marshals as JSON.
func (t txdata) TransactionMarshalJSON() ([]byte, error) {
// MarshalJSON marshals as JSON.
func (t txdata) MarshalJSON() ([]byte, error) {
type txdata struct {
AccountNonce hexutil.Uint64 `json:"nonce" gencodec:"required"`
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
......@@ -41,8 +41,8 @@ func (t txdata) TransactionMarshalJSON() ([]byte, error) {
return json.Marshal(&enc)
}
// TransactionUnmarshalJSON unmarshals from JSON.
func (t *txdata) TransactionUnmarshalJSON(input []byte) error {
// UnmarshalJSON unmarshals from JSON.
func (t *txdata) UnmarshalJSON(input []byte) error {
type txdata struct {
AccountNonce *hexutil.Uint64 `json:"nonce" gencodec:"required"`
Price *hexutil.Big `json:"gasPrice" gencodec:"required"`
......
......@@ -14,15 +14,21 @@ import (
func (t TransactionMeta) MarshalJSON() ([]byte, error) {
type TransactionMeta struct {
L1BlockNumber *big.Int `json:"l1BlockNumber"`
L1Timestamp uint64 `json:"l1Timestamp"`
L1MessageSender *common.Address `json:"l1MessageSender" gencodec:"required"`
QueueOrigin *big.Int `json:"queueOrigin" gencodec:"required"`
QueueOrigin QueueOrigin `json:"queueOrigin" gencodec:"required"`
Index *uint64 `json:"index" gencodec:"required"`
QueueIndex *uint64 `json:"queueIndex" gencodec:"required"`
RawTransaction []byte `json:"rawTransaction" gencodec:"required"`
}
var enc TransactionMeta
enc.L1BlockNumber = t.L1BlockNumber
enc.L1Timestamp = t.L1Timestamp
enc.L1MessageSender = t.L1MessageSender
enc.QueueOrigin = t.QueueOrigin
enc.Index = t.Index
enc.QueueIndex = t.QueueIndex
enc.RawTransaction = t.RawTransaction
return json.Marshal(&enc)
}
......@@ -30,9 +36,12 @@ func (t TransactionMeta) MarshalJSON() ([]byte, error) {
func (t *TransactionMeta) UnmarshalJSON(input []byte) error {
type TransactionMeta struct {
L1BlockNumber *big.Int `json:"l1BlockNumber"`
L1Timestamp *uint64 `json:"l1Timestamp"`
L1MessageSender *common.Address `json:"l1MessageSender" gencodec:"required"`
QueueOrigin *big.Int `json:"queueOrigin" gencodec:"required"`
QueueOrigin *QueueOrigin `json:"queueOrigin" gencodec:"required"`
Index *uint64 `json:"index" gencodec:"required"`
QueueIndex *uint64 `json:"queueIndex" gencodec:"required"`
RawTransaction []byte `json:"rawTransaction" gencodec:"required"`
}
var dec TransactionMeta
if err := json.Unmarshal(input, &dec); err != nil {
......@@ -41,6 +50,9 @@ func (t *TransactionMeta) UnmarshalJSON(input []byte) error {
if dec.L1BlockNumber != nil {
t.L1BlockNumber = dec.L1BlockNumber
}
if dec.L1Timestamp != nil {
t.L1Timestamp = *dec.L1Timestamp
}
if dec.L1MessageSender == nil {
return errors.New("missing required field 'l1MessageSender' for TransactionMeta")
}
......@@ -48,10 +60,18 @@ func (t *TransactionMeta) UnmarshalJSON(input []byte) error {
if dec.QueueOrigin == nil {
return errors.New("missing required field 'queueOrigin' for TransactionMeta")
}
t.QueueOrigin = dec.QueueOrigin
t.QueueOrigin = *dec.QueueOrigin
if dec.Index == nil {
return errors.New("missing required field 'index' for TransactionMeta")
}
t.Index = dec.Index
if dec.QueueIndex == nil {
return errors.New("missing required field 'queueIndex' for TransactionMeta")
}
t.QueueIndex = dec.QueueIndex
if dec.RawTransaction == nil {
return errors.New("missing required field 'rawTransaction' for TransactionMeta")
}
t.RawTransaction = dec.RawTransaction
return nil
}
......@@ -187,12 +187,12 @@ func (tx *Transaction) DecodeRLP(s *rlp.Stream) error {
// MarshalJSON encodes the web3 RPC transaction format.
func (tx *Transaction) MarshalJSON() ([]byte, error) {
return tx.data.TransactionMarshalJSON()
return tx.data.MarshalJSON()
}
// UnmarshalJSON decodes the web3 RPC transaction format.
func (tx *Transaction) UnmarshalJSON(input []byte) error {
err := tx.data.TransactionUnmarshalJSON(input)
err := tx.data.UnmarshalJSON(input)
if err != nil {
return err
}
......@@ -254,13 +254,9 @@ func (tx *Transaction) L1BlockNumber() *big.Int {
return &l1BlockNumber
}
// QueueOrigin returns the Queue Origin of the transaction if it exists.
func (tx *Transaction) QueueOrigin() *big.Int {
if tx.meta.QueueOrigin == nil {
return nil
}
queueOrigin := *tx.meta.QueueOrigin
return &queueOrigin
// QueueOrigin returns the Queue Origin of the transaction
func (tx *Transaction) QueueOrigin() QueueOrigin {
return tx.meta.QueueOrigin
}
// Hash hashes the RLP encoding of tx.
......@@ -519,7 +515,7 @@ type Message struct {
l1MessageSender *common.Address
l1BlockNumber *big.Int
queueOrigin *big.Int
queueOrigin QueueOrigin
}
func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *big.Int, gasLimit uint64, gasPrice *big.Int, data []byte, checkNonce bool, l1MessageSender *common.Address, l1BlockNumber *big.Int, queueOrigin QueueOrigin) Message {
......@@ -535,7 +531,7 @@ func NewMessage(from common.Address, to *common.Address, nonce uint64, amount *b
l1BlockNumber: l1BlockNumber,
l1MessageSender: l1MessageSender,
queueOrigin: big.NewInt(int64(queueOrigin)),
queueOrigin: queueOrigin,
}
}
......@@ -550,4 +546,4 @@ func (m Message) CheckNonce() bool { return m.checkNonce }
func (m Message) L1MessageSender() *common.Address { return m.l1MessageSender }
func (m Message) L1BlockNumber() *big.Int { return m.l1BlockNumber }
func (m Message) QueueOrigin() *big.Int { return m.queueOrigin }
func (m Message) QueueOrigin() QueueOrigin { return m.queueOrigin }
......@@ -12,7 +12,7 @@ import (
"github.com/ethereum/go-ethereum/common"
)
type QueueOrigin int64
type QueueOrigin uint8
const (
// Possible `queue_origin` values
......@@ -20,13 +20,24 @@ const (
QueueOriginL1ToL2 QueueOrigin = 1
)
func (q QueueOrigin) String() string {
switch q {
case QueueOriginSequencer:
return "sequencer"
case QueueOriginL1ToL2:
return "l1"
default:
return ""
}
}
//go:generate gencodec -type TransactionMeta -out gen_tx_meta_json.go
type TransactionMeta struct {
L1BlockNumber *big.Int `json:"l1BlockNumber"`
L1Timestamp uint64 `json:"l1Timestamp"`
L1MessageSender *common.Address `json:"l1MessageSender" gencodec:"required"`
QueueOrigin *big.Int `json:"queueOrigin" gencodec:"required"`
QueueOrigin QueueOrigin `json:"queueOrigin" gencodec:"required"`
// The canonical transaction chain index
Index *uint64 `json:"index" gencodec:"required"`
// The queue index, nil for queue origin sequencer transactions
......@@ -40,7 +51,7 @@ func NewTransactionMeta(l1BlockNumber *big.Int, l1timestamp uint64, l1MessageSen
L1BlockNumber: l1BlockNumber,
L1Timestamp: l1timestamp,
L1MessageSender: l1MessageSender,
QueueOrigin: big.NewInt(int64(queueOrigin)),
QueueOrigin: queueOrigin,
Index: index,
QueueIndex: queueIndex,
RawTransaction: rawTransaction,
......@@ -83,7 +94,7 @@ func TxMetaDecode(input []byte) (*TransactionMeta, error) {
}
if !isNullValue(qo) {
queueOrigin := new(big.Int).SetBytes(qo)
meta.QueueOrigin = queueOrigin
meta.QueueOrigin = QueueOrigin(queueOrigin.Uint64())
}
l, err := common.ReadVarBytes(b, 0, 1024, "L1Timestamp")
......@@ -146,13 +157,9 @@ func TxMetaEncode(meta *TransactionMeta) []byte {
}
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())
}
q := new(bytes.Buffer)
binary.Write(q, binary.LittleEndian, queueOrigin)
common.WriteVarBytes(b, 0, q.Bytes())
l := new(bytes.Buffer)
binary.Write(l, binary.LittleEndian, &meta.L1Timestamp)
......
......@@ -112,14 +112,7 @@ func isTxMetaEqual(meta1 *TransactionMeta, meta2 *TransactionMeta) bool {
}
}
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()) {
if meta1.QueueOrigin != meta2.QueueOrigin {
return false
}
......
......@@ -122,7 +122,7 @@ type CallMsg struct {
L1MessageSender *common.Address
L1BlockNumber *big.Int
QueueOrigin *big.Int
QueueOrigin types.QueueOrigin
}
// A ContractCaller provides contract calls, essentially transactions that are executed by
......
......@@ -1364,14 +1364,8 @@ func newRPCTransaction(tx *types.Transaction, blockHash common.Hash, blockNumber
if meta.L1BlockNumber != nil {
result.L1BlockNumber = (*hexutil.Big)(meta.L1BlockNumber)
}
if meta.QueueOrigin != nil {
switch meta.QueueOrigin.Uint64() {
case uint64(types.QueueOriginSequencer):
result.QueueOrigin = "sequencer"
case uint64(types.QueueOriginL1ToL2):
result.QueueOrigin = "l1"
}
}
result.QueueOrigin = fmt.Sprint(meta.QueueOrigin)
if meta.Index != nil {
index := (hexutil.Uint64)(*meta.Index)
......@@ -2168,7 +2162,7 @@ func (api *PrivateDebugAPI) IngestTransactions(txs []*RPCTransaction) error {
L1BlockNumber: l1BlockNumber,
L1Timestamp: l1Timestamp,
L1MessageSender: tx.L1TxOrigin,
QueueOrigin: big.NewInt(int64(queueOrigin)),
QueueOrigin: queueOrigin,
Index: (*uint64)(tx.Index),
QueueIndex: (*uint64)(tx.QueueIndex),
RawTransaction: rawTransaction,
......
......@@ -869,7 +869,7 @@ func (w *worker) commitNewTx(tx *types.Transaction) error {
// transactions as the timestamp cannot be malleated
if parent.Time() > tx.L1Timestamp() {
log.Error("Monotonicity violation", "index", num)
if tx.QueueOrigin().Uint64() == uint64(types.QueueOriginSequencer) {
if tx.QueueOrigin() == types.QueueOriginSequencer {
tx.SetL1Timestamp(parent.Time())
prev := parent.Transactions()
if len(prev) == 1 {
......
......@@ -644,7 +644,7 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error {
// Queue Origin L1 to L2 transactions must have a timestamp that is set by
// the L1 block that holds the transaction. This should never happen but is
// a sanity check to prevent fraudulent execution.
if tx.QueueOrigin().Uint64() == uint64(types.QueueOriginL1ToL2) {
if tx.QueueOrigin() == types.QueueOriginL1ToL2 {
if tx.L1Timestamp() == 0 {
return fmt.Errorf("Queue origin L1 to L2 transaction without a timestamp: %s", tx.Hash().Hex())
}
......@@ -671,7 +671,7 @@ func (s *SyncService) applyTransactionToTip(tx *types.Transaction) error {
bn := tx.L1BlockNumber()
s.SetLatestL1Timestamp(ts)
s.SetLatestL1BlockNumber(bn.Uint64())
log.Debug("Updating OVM context based on new transaction", "timestamp", ts, "blocknumber", bn.Uint64(), "queue-origin", tx.QueueOrigin().Uint64())
log.Debug("Updating OVM context based on new transaction", "timestamp", ts, "blocknumber", bn.Uint64(), "queue-origin", tx.QueueOrigin())
} else if tx.L1Timestamp() < s.GetLatestL1Timestamp() {
log.Error("Timestamp monotonicity violation", "hash", tx.Hash().Hex())
}
......@@ -790,11 +790,8 @@ func (s *SyncService) ValidateAndApplySequencerTransaction(tx *types.Transaction
log.Trace("Sequencer transaction validation", "hash", tx.Hash().Hex())
qo := tx.QueueOrigin()
if qo == nil {
return errors.New("invalid transaction with no queue origin")
}
if qo.Uint64() != uint64(types.QueueOriginSequencer) {
return fmt.Errorf("invalid transaction with queue origin %d", qo.Uint64())
if qo != types.QueueOriginSequencer {
return fmt.Errorf("invalid transaction with queue origin %d", qo)
}
err := s.txpool.ValidateTx(tx)
if err != nil {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment