From 87002d13182666a7d3b543c88d509232754b8a83 Mon Sep 17 00:00:00 2001 From: Karl Floersch Date: Wed, 2 Jun 2021 19:54:16 -0400 Subject: [PATCH] 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: Mark Tyneway --- .changeset/heavy-planets-return.md | 5 ++++ .../accounts/abi/bind/backends/simulated.go | 2 +- l2geth/core/state_transition.go | 6 ++-- l2geth/core/state_transition_ovm.go | 28 +++--------------- l2geth/core/types/gen_tx_json.go | 8 ++--- l2geth/core/types/gen_tx_meta_json.go | 26 +++++++++++++++-- l2geth/core/types/transaction.go | 20 +++++-------- l2geth/core/types/transaction_meta.go | 29 ++++++++++++------- l2geth/core/types/transaction_meta_test.go | 9 +----- l2geth/interfaces.go | 2 +- l2geth/internal/ethapi/api.go | 12 ++------ l2geth/miner/worker.go | 2 +- l2geth/rollup/sync_service.go | 11 +++---- 13 files changed, 75 insertions(+), 85 deletions(-) create mode 100644 .changeset/heavy-planets-return.md diff --git a/.changeset/heavy-planets-return.md b/.changeset/heavy-planets-return.md new file mode 100644 index 000000000000..c69ceaf05bc6 --- /dev/null +++ b/.changeset/heavy-planets-return.md @@ -0,0 +1,5 @@ +--- +'@eth-optimism/l2geth': patch +--- + +Update queueOrigin type diff --git a/l2geth/accounts/abi/bind/backends/simulated.go b/l2geth/accounts/abi/bind/backends/simulated.go index f00cad5055e6..83701e91f4d5 100644 --- a/l2geth/accounts/abi/bind/backends/simulated.go +++ b/l2geth/accounts/abi/bind/backends/simulated.go @@ -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. diff --git a/l2geth/core/state_transition.go b/l2geth/core/state_transition.go index 933b0f8aa7a8..d66e5769934e 100644 --- a/l2geth/core/state_transition.go +++ b/l2geth/core/state_transition.go @@ -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() } } diff --git a/l2geth/core/state_transition_ovm.go b/l2geth/core/state_transition_ovm.go index 5da13437adba..b9e625d1b7fe 100644 --- a/l2geth/core/state_transition_ovm.go +++ b/l2geth/core/state_transition_ovm.go @@ -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) - } -} diff --git a/l2geth/core/types/gen_tx_json.go b/l2geth/core/types/gen_tx_json.go index f8638522b070..e676058ecc4b 100644 --- a/l2geth/core/types/gen_tx_json.go +++ b/l2geth/core/types/gen_tx_json.go @@ -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"` diff --git a/l2geth/core/types/gen_tx_meta_json.go b/l2geth/core/types/gen_tx_meta_json.go index 13a57551050f..0f99ba918546 100644 --- a/l2geth/core/types/gen_tx_meta_json.go +++ b/l2geth/core/types/gen_tx_meta_json.go @@ -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 } diff --git a/l2geth/core/types/transaction.go b/l2geth/core/types/transaction.go index 1fccae83f679..9f41bd11aaae 100644 --- a/l2geth/core/types/transaction.go +++ b/l2geth/core/types/transaction.go @@ -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 } diff --git a/l2geth/core/types/transaction_meta.go b/l2geth/core/types/transaction_meta.go index 3d09cbd69bff..7f68e6530129 100644 --- a/l2geth/core/types/transaction_meta.go +++ b/l2geth/core/types/transaction_meta.go @@ -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) diff --git a/l2geth/core/types/transaction_meta_test.go b/l2geth/core/types/transaction_meta_test.go index 546d3cb99369..ec630d7bdcd3 100644 --- a/l2geth/core/types/transaction_meta_test.go +++ b/l2geth/core/types/transaction_meta_test.go @@ -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 } diff --git a/l2geth/interfaces.go b/l2geth/interfaces.go index ab3f44eb86fc..aaf10f31c5d7 100644 --- a/l2geth/interfaces.go +++ b/l2geth/interfaces.go @@ -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 diff --git a/l2geth/internal/ethapi/api.go b/l2geth/internal/ethapi/api.go index b1b2fe327aa1..a8b3852c6e14 100644 --- a/l2geth/internal/ethapi/api.go +++ b/l2geth/internal/ethapi/api.go @@ -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, diff --git a/l2geth/miner/worker.go b/l2geth/miner/worker.go index c7746e6d9fd7..3d9e10defb4f 100644 --- a/l2geth/miner/worker.go +++ b/l2geth/miner/worker.go @@ -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 { diff --git a/l2geth/rollup/sync_service.go b/l2geth/rollup/sync_service.go index 0b71d20193ee..a950c724e369 100644 --- a/l2geth/rollup/sync_service.go +++ b/l2geth/rollup/sync_service.go @@ -649,7 +649,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()) } @@ -676,7 +676,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()) } @@ -795,11 +795,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 {